01: // Copyright 2007 The Apache Software Foundation
02: //
03: // Licensed under the Apache License, Version 2.0 (the "License");
04: // you may not use this file except in compliance with the License.
05: // You may obtain a copy of the License at
06: //
07: // http://www.apache.org/licenses/LICENSE-2.0
08: //
09: // Unless required by applicable law or agreed to in writing, software
10: // distributed under the License is distributed on an "AS IS" BASIS,
11: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12: // See the License for the specific language governing permissions and
13: // limitations under the License.
14:
15: package org.apache.tapestry.hibernate;
16:
17: import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
18:
19: import org.apache.tapestry.internal.InternalConstants;
20: import org.apache.tapestry.internal.hibernate.HibernateSessionManagerImpl;
21: import org.apache.tapestry.internal.hibernate.HibernateSessionSourceImpl;
22: import org.apache.tapestry.ioc.Configuration;
23: import org.apache.tapestry.ioc.ServiceBinder;
24: import org.apache.tapestry.ioc.annotations.Inject;
25: import org.apache.tapestry.ioc.annotations.InjectService;
26: import org.apache.tapestry.ioc.annotations.Scope;
27: import org.apache.tapestry.ioc.annotations.Symbol;
28: import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
29: import org.apache.tapestry.ioc.services.ThreadCleanupHub;
30: import org.apache.tapestry.services.AliasContribution;
31: import org.hibernate.Session;
32: import org.hibernate.Transaction;
33:
34: public class HibernateModule {
35: public static void bind(ServiceBinder binder) {
36: binder.bind(HibernateSessionSource.class,
37: HibernateSessionSourceImpl.class);
38: }
39:
40: /**
41: * Contributes the package "<root>.entities" to the configuration, so that it will be
42: * scanned for annotated entity classes.
43: */
44: public static void contributeHibernateSessionSource(
45: Configuration<String> configuration,
46:
47: @Inject
48: @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
49: String appRootPackage) {
50: configuration.add(appRootPackage + ".entities");
51: }
52:
53: /**
54: * The session manager manages sessions on a per-thread/per-request basis. A {@link Transaction}
55: * is created initially, and is committed at the end of the request.
56: */
57: @Scope(PERTHREAD_SCOPE)
58: public static HibernateSessionManager build(
59: HibernateSessionSource sessionSource,
60: ThreadCleanupHub threadCleanupHub) {
61: HibernateSessionManagerImpl service = new HibernateSessionManagerImpl(
62: sessionSource);
63:
64: threadCleanupHub.addThreadCleanupListener(service);
65:
66: return service;
67: }
68:
69: public static Session build(HibernateSessionManager sessionManager,
70: PropertyShadowBuilder propertyShadowBuilder) {
71: // Here's the thing: the tapestry.hibernate.Session class doesn't have to be per-thread,
72: // since
73: // it will invoke getSession() on the HibernateSessionManager service (which is per-thread).
74: // On
75: // first invocation per request,
76: // this forces the HSM into existence (which creates the session and begins the
77: // transaction).
78: // Thus we don't actually create
79: // a session until we first try to access it, then the session continues to exist for the
80: // rest
81: // of the request.
82:
83: return propertyShadowBuilder.build(sessionManager, "session",
84: Session.class);
85: }
86:
87: /**
88: * Contributes the {@link #build(HibernateSessionManager, PropertyShadowBuilder) Session}
89: * service.
90: */
91: public static void contributeAlias(
92: Configuration<AliasContribution> configuration,
93:
94: @InjectService("Session")
95: Session session) {
96: configuration.add(AliasContribution.create(Session.class,
97: session));
98: }
99: }
|