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.jetspeed.components.portletentity;
018:
019: import java.io.IOException;
020: import java.rmi.server.UID;
021: import java.util.Collection;
022: import java.util.Iterator;
023: import java.util.prefs.BackingStoreException;
024:
025: import org.apache.jetspeed.components.portletregistry.PortletRegistry;
026: import org.apache.jetspeed.container.window.PortletWindowAccessor;
027: import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
028: import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
029: import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
030: import org.apache.jetspeed.om.page.ContentFragment;
031: import org.apache.jetspeed.om.page.Fragment;
032: import org.apache.jetspeed.om.preference.impl.PrefsPreferenceSetImpl;
033: import org.apache.jetspeed.page.PageManager;
034: import org.apache.jetspeed.request.RequestContextComponent;
035: import org.apache.jetspeed.util.JetspeedObjectID;
036: import org.apache.ojb.broker.query.Criteria;
037: import org.apache.ojb.broker.query.Query;
038: import org.apache.ojb.broker.query.QueryFactory;
039: import org.apache.pluto.om.common.ObjectID;
040: import org.apache.pluto.om.common.PreferenceSet;
041: import org.apache.pluto.om.entity.PortletEntity;
042: import org.apache.pluto.om.entity.PortletEntityCtrl;
043: import org.apache.pluto.om.portlet.PortletDefinition;
044: import org.apache.pluto.om.window.PortletWindow;
045: import org.springframework.orm.ojb.support.PersistenceBrokerDaoSupport;
046:
047: /**
048: * <p>
049: * PersistenceStorePortletEntityAccess
050: * </p>
051: * <p>
052: *
053: * </p>
054: *
055: * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
056: * @version $Id: PersistenceBrokerPortletEntityAccess.java,v 1.5 2005/04/29 13:59:08 weaver Exp $
057: *
058: */
059: public class PersistenceBrokerPortletEntityAccess extends
060: PersistenceBrokerDaoSupport implements
061: PortletEntityAccessComponent {
062: private PortletRegistry registry;
063: private PortletWindowAccessor windowAccessor = null;
064:
065: // 2006-08-22: by default, do not merge preferences from the shared preferences area
066: // up until this point, all preferences were shared. With JS2-449, preferences are now
067: // stored 'per user'. The username is stored in the preferences FULL_PATH
068: // To turn on mergeSharedPreferences configure this property to true
069: // in your Spring configuration
070: boolean mergeSharedPreferences = false;
071:
072: /**
073: *
074: * @param registry
075: */
076: public PersistenceBrokerPortletEntityAccess(PortletRegistry registry) {
077: super ();
078: this .registry = registry;
079: PortletEntityImpl.registry = registry;
080: }
081:
082: public PersistenceBrokerPortletEntityAccess(
083: PortletRegistry registry, RequestContextComponent rcc) {
084: super ();
085: this .registry = registry;
086: PortletEntityImpl.registry = registry;
087: PortletEntityImpl.rcc = rcc;
088: }
089:
090: public PersistenceBrokerPortletEntityAccess(
091: PortletRegistry registry, RequestContextComponent rcc,
092: PageManager pageManager) {
093: super ();
094: this .registry = registry;
095: PortletEntityImpl.registry = registry;
096: PortletEntityImpl.rcc = rcc;
097: PortletEntityImpl.pm = pageManager;
098: }
099:
100: public PersistenceBrokerPortletEntityAccess(
101: PortletRegistry registry, RequestContextComponent rcc,
102: PageManager pageManager, boolean mergeSharedPreferences) {
103: super ();
104: this .registry = registry;
105: PortletEntityImpl.registry = registry;
106: PortletEntityImpl.rcc = rcc;
107: PortletEntityImpl.pm = pageManager;
108: this .mergeSharedPreferences = mergeSharedPreferences;
109: }
110:
111: public void setEntityAccessProxy(PortletEntityAccessComponent proxy) {
112: PortletEntityImpl.pac = proxy;
113: }
114:
115: public void setPageManager(PageManager pageManager) {
116: PortletEntityImpl.pm = pageManager;
117: }
118:
119: /**
120: *
121: * <p>
122: * generateEntityFromFragment
123: * </p>
124: *
125: * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityFromFragment(org.apache.jetspeed.om.page.Fragment,
126: * java.lang.String)
127: * @param fragment
128: * @param principal
129: * @return @throws
130: * PortletEntityNotGeneratedException
131: */
132: public MutablePortletEntity generateEntityFromFragment(
133: ContentFragment fragment, String principal)
134: throws PortletEntityNotGeneratedException {
135: PortletDefinition pd = registry
136: .getPortletDefinitionByUniqueName(fragment.getName());
137: ObjectID entityKey = generateEntityKey(fragment, principal);
138: MutablePortletEntity portletEntity = null;
139:
140: if (pd != null) {
141: portletEntity = newPortletEntityInstance(pd);
142: if (portletEntity == null) {
143: throw new PortletEntityNotGeneratedException(
144: "Failed to create Portlet Entity for "
145: + fragment.getName());
146: }
147: } else {
148: String msg = "Failed to retrieve Portlet Definition for "
149: + fragment.getName();
150: logger.warn(msg);
151: portletEntity = new PortletEntityImpl(fragment);
152: fragment.overrideRenderedContent(msg);
153: }
154:
155: portletEntity.setId(entityKey.toString());
156:
157: return portletEntity;
158: }
159:
160: /**
161: *
162: * <p>
163: * generateEntityFromFragment
164: * </p>
165: *
166: * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityFromFragment(org.apache.jetspeed.om.page.Fragment)
167: * @param fragment
168: * @return @throws
169: * PortletEntityNotGeneratedException
170: */
171: public MutablePortletEntity generateEntityFromFragment(
172: ContentFragment fragment)
173: throws PortletEntityNotGeneratedException {
174: return generateEntityFromFragment(fragment, null);
175: }
176:
177: /**
178: *
179: * <p>
180: * generateEntityKey
181: * </p>
182: *
183: * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#generateEntityKey(org.apache.jetspeed.om.page.Fragment,
184: * java.lang.String)
185: * @param fragment
186: * @param principal
187: * @return
188: */
189: public ObjectID generateEntityKey(Fragment fragment,
190: String principal) {
191: StringBuffer key = new StringBuffer();
192: if (principal != null && principal.length() > 0) {
193: key.append(principal);
194: key.append("/");
195: }
196: key.append(fragment.getId());
197: return JetspeedObjectID.createFromString(key.toString());
198: }
199:
200: /**
201: *
202: * <p>
203: * getPortletEntities
204: * </p>
205: *
206: * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#getPortletEntities(org.apache.pluto.om.portlet.PortletDefinition)
207: * @param portletDefinition
208: * @return
209: */
210: public Collection getPortletEntities(
211: PortletDefinition portletDefinition) {
212: Criteria c = new Criteria();
213: String appName = ((MutablePortletApplication) portletDefinition
214: .getPortletApplicationDefinition()).getName();
215: String portletName = portletDefinition.getName();
216: c.addEqualTo("appName", appName);
217: c.addEqualTo("portletName", portletName);
218:
219: return getPersistenceBrokerTemplate().getCollectionByQuery(
220: QueryFactory.newQuery(PortletEntityImpl.class, c));
221: }
222:
223: public Collection getPortletEntities(String portletUniqueName) {
224: String[] split = portletUniqueName.split("::");
225: String appName = split[0];
226: String portletName = split[1];
227: Criteria c = new Criteria();
228: c.addEqualTo("appName", appName);
229: c.addEqualTo("portletName", portletName);
230:
231: return getPersistenceBrokerTemplate().getCollectionByQuery(
232: QueryFactory.newQuery(PortletEntityImpl.class, c));
233: }
234:
235: public MutablePortletEntity getPortletEntity(ObjectID id) {
236: try {
237: return getPortletEntity(id, null);
238: }
239: // This exception is only thrown if a Fragment has been passed into the
240: // getPortletEntity() method. This should never happen.
241: catch (PortletEntityNotStoredException e) {
242: IllegalStateException ise = new IllegalStateException(
243: "Unexepected error while retrieving portlet entity "
244: + id);
245: ise.initCause(e);
246: throw ise;
247: }
248: }
249:
250: protected MutablePortletEntity getPortletEntity(ObjectID id,
251: ContentFragment fragment)
252: throws PortletEntityNotStoredException {
253: Criteria c = new Criteria();
254: c.addEqualTo("id", id.toString());
255: Query q = QueryFactory.newQuery(PortletEntityImpl.class, c);
256: MutablePortletEntity portletEntity = (MutablePortletEntity) getPersistenceBrokerTemplate()
257: .getObjectByQuery(q);
258: if (portletEntity == null) {
259: return null;
260: } else {
261: String portletUniqueName = portletEntity
262: .getPortletUniqueName();
263: PortletDefinitionComposite parentPortletDef = registry
264: .getPortletDefinitionByUniqueName(portletUniqueName);
265: if (parentPortletDef != null) {
266: //Indication that the fragment has changed the portlet it references.
267: if (fragment != null
268: && !portletUniqueName
269: .equals(fragment.getName())) {
270: parentPortletDef = registry
271: .getPortletDefinitionByUniqueName(fragment
272: .getName());
273: ((PortletEntityCtrl) portletEntity)
274: .setPortletDefinition(parentPortletDef);
275: storePortletEntity(portletEntity);
276: } else {
277: ((PortletEntityCtrl) portletEntity)
278: .setPortletDefinition(parentPortletDef);
279: }
280: } else if (fragment != null && parentPortletDef == null) {
281: // If we have no porlet definition but have a fragment, we see if the
282: // unique name has changed and access the portlet definition
283: // using that unique name.
284: parentPortletDef = registry
285: .getPortletDefinitionByUniqueName(fragment
286: .getName());
287: if (parentPortletDef != null) {
288: ((PortletEntityCtrl) portletEntity)
289: .setPortletDefinition(parentPortletDef);
290: storePortletEntity(portletEntity);
291: }
292: }
293:
294: if (parentPortletDef == null) {
295: final String msg = "Portlet " + portletUniqueName
296: + " not found";
297: String content = fragment.getOverriddenContent();
298: if (content == null || !content.equals(msg)) {
299: fragment.overrideRenderedContent(msg);
300: logger.error(msg);
301: }
302: }
303:
304: return portletEntity;
305: }
306: }
307:
308: public MutablePortletEntity getPortletEntity(String id) {
309: ObjectID oid = JetspeedObjectID.createFromString(id);
310: return getPortletEntity(oid);
311: }
312:
313: public MutablePortletEntity getPortletEntityForFragment(
314: ContentFragment fragment, String principal)
315: throws PortletEntityNotStoredException {
316: return getPortletEntity(generateEntityKey(fragment, principal),
317: fragment);
318: }
319:
320: public MutablePortletEntity getPortletEntityForFragment(
321: ContentFragment fragment)
322: throws PortletEntityNotStoredException {
323: return getPortletEntity(generateEntityKey(fragment, null),
324: fragment);
325: }
326:
327: public MutablePortletEntity newPortletEntityInstance(
328: PortletDefinition portletDefinition) {
329: return newPortletEntityInstance(portletDefinition,
330: autoGenerateID(portletDefinition));
331: }
332:
333: public MutablePortletEntity newPortletEntityInstance(
334: PortletDefinition portletDefinition, String id) {
335: PortletEntityImpl portletEntity = new PortletEntityImpl();
336: portletEntity.setPortletDefinition(portletDefinition);
337: portletEntity.setId(id);
338: return portletEntity;
339: }
340:
341: public void removeFromCache(PortletEntity entity) {
342: if (windowAccessor != null) {
343: String windowId = entity.getId().toString();
344: PortletWindow window = windowAccessor
345: .getPortletWindow(windowId);
346: if (window != null) {
347: windowAccessor.removeWindow(window);
348: }
349: }
350: }
351:
352: public void removePortletEntities(
353: PortletDefinition portletDefinition)
354: throws PortletEntityNotDeletedException {
355: Iterator entities = getPortletEntities(portletDefinition)
356: .iterator();
357: while (entities.hasNext()) {
358: PortletEntity entity = (PortletEntity) entities.next();
359: removePortletEntity(entity);
360: }
361:
362: }
363:
364: public void removePortletEntity(PortletEntity portletEntity)
365: throws PortletEntityNotDeletedException {
366: PreferenceSet prefsSet = portletEntity.getPreferenceSet();
367: getPersistenceBrokerTemplate().delete(portletEntity);
368:
369: if (prefsSet instanceof PrefsPreferenceSetImpl) {
370: try {
371: ((PrefsPreferenceSetImpl) prefsSet).clear();
372: removeFromCache(portletEntity);
373: } catch (BackingStoreException e) {
374: throw new PortletEntityNotDeletedException(
375: "Failed to remove preferences for portlet entity "
376: + portletEntity.getId() + ". "
377: + e.getMessage(), e);
378: }
379: }
380: }
381:
382: /**
383: * <p>
384: * updatePortletEntity
385: * </p>
386: *
387: * Updates portlet definition associated with the portlet
388: * entity to match the fragment configuration
389: *
390: * @param portletEntity
391: * @param fragment
392: * @throws PortletEntityNotStoredException
393: */
394: public void updatePortletEntity(PortletEntity portletEntity,
395: ContentFragment fragment)
396: throws PortletEntityNotStoredException {
397: // validate portlet entity id
398: if (!fragment.getId().equals(portletEntity.getId().toString())) {
399: throw new PortletEntityNotStoredException(
400: "Fragment and PortletEntity ids do not match, update skipped: "
401: + fragment.getId() + " != "
402: + portletEntity.getId());
403: }
404:
405: // update portlet definition from fragment
406: PortletDefinition pd = registry
407: .getPortletDefinitionByUniqueName(fragment.getName());
408: if (pd != null) {
409: ((PortletEntityImpl) portletEntity)
410: .setPortletDefinition(pd);
411: } else {
412: throw new PortletEntityNotStoredException(
413: "Fragment PortletDefinition not found: "
414: + fragment.getName());
415: }
416: }
417:
418: public void storePortletEntity(PortletEntity portletEntity)
419: throws PortletEntityNotStoredException {
420: try {
421: ((PortletEntityCtrl) portletEntity).store();
422: } catch (Exception e) {
423: throw new PortletEntityNotStoredException(e.toString(), e);
424: }
425:
426: }
427:
428: /**
429: * <p>
430: * storePreferenceSet
431: * </p>
432: *
433: * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#storePreferenceSet(org.apache.pluto.om.common.PreferenceSet)
434: * @param prefSet
435: * @throws IOException
436: */
437: public void storePreferenceSet(PreferenceSet prefSet,
438: PortletEntity entity) throws IOException {
439: try {
440: getPersistenceBrokerTemplate().store(entity);
441: if (prefSet != null
442: && prefSet instanceof PrefsPreferenceSetImpl) {
443: ((PrefsPreferenceSetImpl) prefSet).flush();
444: }
445:
446: } catch (Exception e) {
447: String msg = "Failed to store portlet entity:"
448: + e.toString();
449: IOException ioe = new IOException(msg);
450: ioe.initCause(e);
451: throw ioe;
452: }
453:
454: }
455:
456: protected String autoGenerateID(PortletDefinition pd) {
457: String appName = ((MutablePortletApplication) pd
458: .getPortletApplicationDefinition()).getName();
459: String portletName = pd.getName();
460: return appName + "::" + portletName + "::"
461: + new UID().toString();
462: }
463:
464: /* (non-Javadoc)
465: * @see org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent#isMergeSharedPreferences()
466: */
467: public boolean isMergeSharedPreferences() {
468: return this.mergeSharedPreferences;
469: }
470:
471: }
|