001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.core.impl.model.instance.persistent;
023:
024: import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
025: import org.apache.log4j.Logger;
026: import org.hibernate.Query;
027: import org.hibernate.Session;
028: import org.hibernate.SessionFactory;
029: import org.hibernate.exception.ConstraintViolationException;
030: import org.jboss.portal.common.util.Tools;
031: import org.jboss.portal.core.impl.model.instance.AbstractInstance;
032: import org.jboss.portal.core.impl.model.instance.AbstractInstanceCustomization;
033: import org.jboss.portal.core.impl.model.instance.AbstractInstanceDefinition;
034: import org.jboss.portal.core.impl.model.instance.InstanceContainerImpl;
035: import org.jboss.portal.core.impl.model.instance.JBossInstanceContainerContext;
036: import org.jboss.portal.core.model.instance.DuplicateInstanceException;
037: import org.jboss.portal.core.model.instance.InstancePermission;
038: import org.jboss.portal.core.model.instance.metadata.InstanceMetaData;
039: import org.jboss.portal.jems.hibernate.ObjectContextualizer;
040: import org.jboss.portal.portlet.PortletContext;
041: import org.jboss.portal.security.PortalSecurityException;
042: import org.jboss.portal.security.RoleSecurityBinding;
043: import org.jboss.portal.security.spi.auth.PortalAuthorizationManager;
044: import org.jboss.portal.security.spi.auth.PortalAuthorizationManagerFactory;
045:
046: import javax.naming.InitialContext;
047: import java.util.Collection;
048: import java.util.Iterator;
049: import java.util.Set;
050:
051: /**
052: * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
053: * @version $Revision: 9295 $
054: */
055: public class PersistentInstanceContainerContext implements
056: JBossInstanceContainerContext {
057:
058: /** . */
059: private static final Logger log = Logger
060: .getLogger(PersistentInstanceContainerContext.class);
061:
062: /** . */
063: private static final String BY_INSTANCE_ID_QUERY = "from "
064: + Tools.getShortNameOf(PersistentInstanceDefinition.class)
065: + " where instanceId=:instanceId";
066:
067: /** . */
068: private static final String FROM_INSTANCE_DEFINITION_IMPL = "from "
069: + Tools.getShortNameOf(PersistentInstanceDefinition.class);
070:
071: /** . */
072: protected SessionFactory sessionFactory;
073:
074: /** . */
075: protected String sessionFactoryJNDIName;
076:
077: /** . */
078: protected ObjectContextualizer contextualizer;
079:
080: /** . */
081: protected ConcurrentReaderHashMap cache;
082:
083: /** . */
084: protected boolean cacheNaturalId;
085:
086: /** . */
087: private InstanceContainerImpl container;
088:
089: public PersistentInstanceContainerContext() {
090: this .contextualizer = new ObjectContextualizer(this );
091: this .cache = new ConcurrentReaderHashMap();
092: }
093:
094: public InstanceContainerImpl getContainer() {
095: return container;
096: }
097:
098: public void setContainer(InstanceContainerImpl container) {
099: this .container = container;
100: }
101:
102: public void flushNaturalIdCache() {
103: cache.clear();
104: }
105:
106: public int getNaturalIdCacheSize() {
107: return cache.size();
108: }
109:
110: public boolean getCacheNaturalId() {
111: return cacheNaturalId;
112: }
113:
114: public void setCacheNaturalId(boolean cacheNaturalId) {
115: this .cacheNaturalId = cacheNaturalId;
116: }
117:
118: public String getSessionFactoryJNDIName() {
119: return sessionFactoryJNDIName;
120: }
121:
122: public void setSessionFactoryJNDIName(String sessionFactoryJNDIName) {
123: this .sessionFactoryJNDIName = sessionFactoryJNDIName;
124: }
125:
126: public void start() throws Exception {
127: sessionFactory = (SessionFactory) new InitialContext()
128: .lookup(sessionFactoryJNDIName);
129:
130: //
131: contextualizer.attach(sessionFactory);
132: }
133:
134: public void stop() throws Exception {
135: sessionFactory = null;
136: }
137:
138: public Collection getInstanceDefinitions() {
139: Session session = sessionFactory.getCurrentSession();
140:
141: //
142: return session.createQuery(FROM_INSTANCE_DEFINITION_IMPL)
143: .list();
144: }
145:
146: public AbstractInstanceCustomization newInstanceCustomization(
147: AbstractInstanceDefinition def, String id,
148: PortletContext portletContext) {
149: return new PersistentInstanceCustomization(
150: (PersistentInstanceDefinition) def, id, portletContext);
151: }
152:
153: public AbstractInstanceDefinition newInstanceDefinition(String id,
154: String portletRef) {
155: return new PersistentInstanceDefinition(this , id, portletRef);
156: }
157:
158: public AbstractInstanceDefinition newInstanceDefinition(
159: InstanceMetaData instanceMetaData) {
160: return new PersistentInstanceDefinition(this , instanceMetaData);
161: }
162:
163: public AbstractInstanceDefinition getInstanceDefinition(String id) {
164: // Get cached pk from natural id
165: Long pk = cacheNaturalId ? (Long) cache.get(id) : null;
166:
167: //
168: PersistentInstanceDefinition instance;
169:
170: //
171: Session session = sessionFactory.getCurrentSession();
172:
173: //
174: if (pk == null) {
175: // No pk
176: instance = lookupNoCache(session, id);
177: } else {
178: // Try lookup using the cached pk
179: instance = (PersistentInstanceDefinition) session.get(
180: PersistentInstanceDefinition.class, pk);
181:
182: // The pk may be invalid if the instance has been recreted under the same path with a different pk
183: if (instance == null) {
184: // In that case we try a no cache
185: instance = lookupNoCache(session, id);
186: }
187: }
188:
189: //
190: if (cacheNaturalId) {
191: if (instance != null) {
192: cache.put(id, instance.getKey());
193: } else {
194: cache.remove(id);
195: }
196: }
197:
198: //
199: return instance;
200: }
201:
202: public AbstractInstanceCustomization getCustomization(
203: AbstractInstanceDefinition instanceDef,
204: String customizationId) {
205: PersistentInstanceDefinition _instanceDef = (PersistentInstanceDefinition) instanceDef;
206: return (PersistentInstanceCustomization) _instanceDef.relatedCustomizations
207: .get(customizationId);
208: }
209:
210: private PersistentInstanceDefinition lookupNoCache(Session session,
211: String id) {
212: Query q = session.createQuery(BY_INSTANCE_ID_QUERY);
213: q.setString("instanceId", id);
214: return (PersistentInstanceDefinition) q.uniqueResult();
215: }
216:
217: public void createInstanceDefinition(
218: AbstractInstanceDefinition instanceDef)
219: throws DuplicateInstanceException {
220: String id = instanceDef.getId();
221:
222: //
223: if (getInstanceDefinition(id) != null) {
224: throw new DuplicateInstanceException("An instance with id "
225: + id + " already exist");
226: }
227:
228: //
229: try {
230: Session session = sessionFactory.getCurrentSession();
231: session.persist(instanceDef);
232: } catch (ConstraintViolationException e) {
233: // May raise a constraint violation exception if it is has been inserted between the lookup
234: // and the insert and the isolation level is not serializable
235: throw new DuplicateInstanceException("An instance with id "
236: + id + " already exist");
237: }
238: }
239:
240: public void createInstanceCustomizaton(
241: AbstractInstanceCustomization customization) {
242: createInstanceCustomizaton((PersistentInstanceCustomization) customization);
243: }
244:
245: private void createInstanceCustomizaton(
246: PersistentInstanceCustomization customization) {
247: Session session = sessionFactory.getCurrentSession();
248:
249: // Persist in db
250: session.persist(customization);
251:
252: // Get owner that will become the related definition
253: PersistentInstanceDefinition relatedDefinition = customization.owner;
254:
255: // Create one to many assoication
256: relatedDefinition.relatedCustomizations.put(
257: customization.customizationId, customization);
258: customization.relatedDefinition = relatedDefinition;
259:
260: // Update state
261: session.update(customization.relatedDefinition);
262:
263: // Mark state as persistent
264: customization.persistent = true;
265: }
266:
267: private void updateInstance(AbstractInstance instanceDef) {
268: Session session = sessionFactory.getCurrentSession();
269: session.update(instanceDef);
270: }
271:
272: public void updateInstance(AbstractInstance instance,
273: PortletContext portletContext, boolean mutable) {
274: PersistentInstanceDefinition _instance = (PersistentInstanceDefinition) instance;
275:
276: //
277: _instance.setPortletRef(portletContext.getId());
278: _instance.setState(portletContext.getState());
279: _instance.setMutable(mutable);
280:
281: //
282: updateInstance(_instance);
283: }
284:
285: public void updateInstance(AbstractInstance instance,
286: PortletContext portletContext) {
287: instance.setPortletRef(portletContext.getId());
288: instance.setState(portletContext.getState());
289:
290: //
291: updateInstance(instance);
292: }
293:
294: public void updateInstanceDefinition(
295: AbstractInstanceDefinition def, Set securityBindings) {
296: PersistentInstanceDefinition _def = (PersistentInstanceDefinition) def;
297:
298: //
299: for (Iterator i = _def.getRelatedSecurityBindings().values()
300: .iterator(); i.hasNext();) {
301: PersistentRoleSecurityBinding isc = (PersistentRoleSecurityBinding) i
302: .next();
303:
304: // Break association
305: i.remove();
306: isc.setInstance(null);
307: }
308:
309: for (Iterator i = securityBindings.iterator(); i.hasNext();) {
310: RoleSecurityBinding sc = (RoleSecurityBinding) i.next();
311:
312: //
313: PersistentRoleSecurityBinding isc = new PersistentRoleSecurityBinding(
314: sc.getActions(), sc.getRoleName());
315:
316: // Create association
317: isc.setInstance(_def);
318: _def.getRelatedSecurityBindings()
319: .put(sc.getRoleName(), isc);
320: }
321: }
322:
323: public void destroyInstanceDefinition(
324: AbstractInstanceDefinition instanceDef) {
325: destroyInstanceDefinition((PersistentInstanceDefinition) instanceDef);
326: }
327:
328: private void destroyInstanceDefinition(
329: PersistentInstanceDefinition instanceDef) {
330: Session session = sessionFactory.getCurrentSession();
331:
332: // Destroy the user instances
333: Collection customizations = instanceDef
334: .getRelatedCustomizations().values();
335: for (Iterator i = customizations.iterator(); i.hasNext();) {
336: PersistentInstanceCustomization userInstance = (PersistentInstanceCustomization) i
337: .next();
338: i.remove();
339: userInstance.relatedDefinition = null;
340: session.delete(userInstance);
341: }
342:
343: // Delete instance
344: session.delete(instanceDef);
345:
346: //
347: session.flush();
348: }
349:
350: public void destroyInstanceCustomization(
351: AbstractInstanceCustomization customization) {
352: destroyInstanceCustomization((PersistentInstanceCustomization) customization);
353: }
354:
355: private void destroyInstanceCustomization(
356: PersistentInstanceCustomization customization) {
357: Session session = sessionFactory.getCurrentSession();
358:
359: // Delete relationship
360: customization.relatedDefinition.relatedCustomizations
361: .remove(customization.getId());
362: customization.relatedDefinition = null;
363:
364: // Delete customization
365: session.delete(customization);
366:
367: //
368: session.flush();
369: }
370:
371: public boolean checkPermission(InstancePermission perm) {
372: if (container.getPerformSecurityChecks()) {
373: boolean result = false;
374: try {
375: PortalAuthorizationManagerFactory pamf = container
376: .getPortalAuthorizationManagerFactory();
377: PortalAuthorizationManager manager = pamf.getManager();
378: result = manager.checkPermission(perm);
379: } catch (PortalSecurityException e) {
380: log.error("Cannot check instance permission", e);
381: }
382: return result;
383: } else {
384: return true;
385: }
386: }
387: }
|