/home/mario/oci/jnb/dataaccess/source/src/java/com/ociweb/service/ServiceLocatorImpl.java
|
1 /**
2 * This software program, Simple Data Access Layer (SDAL), is copyrighted by Object
3 * Computing inc of St. Louis MO USA. It is provided under the open-source model
4 * and is free of license fees. You are free to modify this code for your own use
5 * but you may not claim copyright.
6 *
7 * Since SDAL is open source and free of licensing fees, you are free to use,
8 * modify, and distribute the source code, as long as you include this copyright
9 * statement.
10 *
11 * In particular, you can use SDAL to build proprietary software and are under no
12 * obligation to redistribute any of your source code that is built using SDAL.
13 * Note, however, that you may not do anything to the SDAL code, such as
14 * copyrighting it yourself or claiming authorship of the SDAL code, that will
15 * prevent SDAL from being distributed freely using an open source development
16 * model.
17 *
18 * Warranty
19 * LICENSED PRODUCT, SDAL, IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
20 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE,
21 * NONINFRINGEMENT, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
22 *
23 * Support
24 * LICENSED PRODUCT, SDAL, IS PROVIDED WITH NO SUPPORT AND WITHOUT ANY OBLIGATION ON THE
25 * PART OF OCI OR ANY OF ITS SUBSIDIARIES OR AFFILIATES TO ASSIST IN ITS USE,
26 * CORRECTION, MODIFICATION OR ENHANCEMENT.
27 *
28 * Support may be available from OCI to users who have agreed to a support
29 * contract.
30 *
31 * Liability
32 * OCI OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH
33 * RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
34 * LICENSED PRODUCT OR ANY PART THEREOF.
35 *
36 * IN NO EVENT WILL OCI OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR ANY
37 * LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL DAMAGES,
38 * EVEN IF OCI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
39 *
40 * Copyright OCI. St. Louis MO USA, 2004
41 *
42 */
43 package com.ociweb.service;
44
45 import com.ociweb.service.ServiceLocator;
46 import com.ociweb.service.ServiceLocatorException;
47 import com.ociweb.service.*;
48
49 import java.lang.reflect.InvocationHandler;
50 import java.lang.reflect.Method;
51 import java.lang.reflect.Proxy;
52 import java.util.*;
53
54 import net.sf.hibernate.Session;
55 import net.sf.hibernate.HibernateException;
56 import org.apache.log4j.Logger;
57 import org.apache.log4j.LogManager;
58
59 class ServiceLocatorImpl implements ServiceLocator {
60 private static final Map COMMANDS = new Hashtable();
61 private static final Command FIND_WITH_NAMED_QUERY_COMMAND = new FindWithNamedQueryCommand();
62 private List validatedClasses = new Vector();
63
64 public ServiceLocatorImpl() {
65 COMMANDS.put("add", new AddCommand());
66 COMMANDS.put("update", new UpdateCommand());
67 COMMANDS.put("remove", new RemoveCommand());
68 COMMANDS.put("findByPrimaryKey", new FindByPrimaryKeyCommand());
69 COMMANDS.put("findAll", new FindAllCommand());
70 }
71
72 public Object getDomainObjectManager(Class managerClass) throws ServiceLocatorException {
73 validate(managerClass);
74 return Proxy.newProxyInstance(managerClass.getClassLoader(), new Class[]{managerClass},
75 new ManagerDelegate());
76 }
77
78 private void validate(Class managerClass) throws ServiceLocatorException {
79 if (!validatedClasses.contains(managerClass)) {
80 validateIsInterface(managerClass);
81 validateHasCRUDlikeAPI(managerClass);
82 validatedClasses.add(managerClass);
83 }
84 }
85
86 private void validateIsInterface(Class managerClass) throws ServiceLocatorException {
87 if (!managerClass.isInterface()) {
88 throw exceptionFactory(managerClass, " is not an Interface");
89 }
90 }
91
92 private void validateHasCRUDlikeAPI(Class managerClass) throws ServiceLocatorException {
93 Method[] methods = managerClass.getMethods();
94 List mgrMethods = new ArrayList(methods.length);
95 for (int i = 0; i < methods.length; i++) {
96 Method method = methods[i];
97 mgrMethods.add(method.getName());
98 }
99 if (!mgrMethods.containsAll(COMMANDS.keySet())) {
100 throw exceptionFactory(managerClass,
101 " must contain all of the following methods: 'add', 'update', 'remove', " +
102 "'findByPrimaryKey', 'findAll'");
103 }
104 }
105
106 private ServiceLocatorException exceptionFactory(Class managerClass, String message) {
107 return new ServiceLocatorException("The supplied Class object (" + managerClass.getName() + ") " + message);
108 }
109
110 private static class ManagerDelegate implements InvocationHandler {
111 private Logger log = LogManager.getLogger(getClass());
112
113 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
114 Command command = resolveCommand(method);
115 if (command == null) {
116 throw new UnsupportedOperationException();
117 }
118 try {
119 return command.execute(method, args, getSession());
120 } catch (Exception e) {
121 invalidateSession();
122 throw e;
123 }
124 }
125
126 private Command resolveCommand(Method method) {
127 Command result = (Command) COMMANDS.get(method.getName());
128 if (result == null && method.getName().startsWith("find")) {
129 //If it is not one of the default commands but it begins with 'find', assume it is a finder for
130 //named queries
131 result = FIND_WITH_NAMED_QUERY_COMMAND;
132 }
133 return result;
134 }
135
136 private Session getSession() throws SessionException {
137 Session session = ThreadSessionHolder.get();
138
139 if (!session.isConnected()) {
140 try {
141 session.reconnect();
142 } catch (HibernateException he) {
143 throw new SessionException("Could not reconnect the session", he);
144 }
145 }
146 return session;
147 }
148
149 private void invalidateSession() {
150 try {
151 ThreadSessionHolder.get().close();
152 } catch (HibernateException e) {
153 log.error("Unable to close the session");
154 }
155 ThreadSessionHolder.set(null);
156 }
157 }
158 }
159