root/trunk/components/server/src/ome/logic/ConfigImpl.java
| Revision 2128, 9.6 kB (checked in by jmoore, 11 months ago) | |
|---|---|
|
|
| Line | |
|---|---|
| 1 | /* |
| 2 | * ome.logic.ConfigImpl |
| 3 | * |
| 4 | * Copyright 2006 University of Dundee. All rights reserved. |
| 5 | * Use is subject to license terms supplied in LICENSE.txt |
| 6 | */ |
| 7 | |
| 8 | /*------------------------------------------------------------------------------ |
| 9 | * |
| 10 | * Written by: Josh Moore <josh.moore@gmx.de> |
| 11 | * |
| 12 | *------------------------------------------------------------------------------ |
| 13 | */ |
| 14 | |
| 15 | package ome.logic; |
| 16 | |
| 17 | // Java imports |
| 18 | import java.util.Date; |
| 19 | |
| 20 | import javax.annotation.security.RolesAllowed; |
| 21 | import javax.ejb.Local; |
| 22 | import javax.ejb.Remote; |
| 23 | import javax.ejb.Stateless; |
| 24 | import javax.ejb.TransactionManagement; |
| 25 | import javax.ejb.TransactionManagementType; |
| 26 | import javax.interceptor.Interceptors; |
| 27 | |
| 28 | // Third-party libraries |
| 29 | import org.jboss.annotation.ejb.LocalBinding; |
| 30 | import org.jboss.annotation.ejb.RemoteBinding; |
| 31 | import org.jboss.annotation.ejb.RemoteBindings; |
| 32 | import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; |
| 33 | import org.springframework.transaction.annotation.Transactional; |
| 34 | |
| 35 | // Application-internal dependencies |
| 36 | import ome.annotations.RevisionDate; |
| 37 | import ome.annotations.RevisionNumber; |
| 38 | import ome.api.IConfig; |
| 39 | import ome.api.ServiceInterface; |
| 40 | import ome.services.util.OmeroAroundInvoke; |
| 41 | import ome.system.Version; |
| 42 | |
| 43 | /** |
| 44 | * implementation of the IConfig service interface. |
| 45 | * |
| 46 | * Also used as the main developer example for developing (stateless) ome.logic |
| 47 | * implementations. See source code documentation for more. |
| 48 | * |
| 49 | * @author Josh Moore, josh.moore at gmx.de |
| 50 | * @version $Revision$, $Date$ |
| 51 | * @since 3.0-M3 |
| 52 | * @see IConfig |
| 53 | */ |
| 54 | |
| 55 | /* |
| 56 | * Developer notes: --------------- The two annotations below are activated by |
| 57 | * setting the subversion properties on this class file. They can be accessed |
| 58 | * via ome.system.Version |
| 59 | */ |
| 60 | @RevisionDate("$Date$") |
| 61 | @RevisionNumber("$Revision$") |
| 62 | /* |
| 63 | * Developer notes: --------------- The annotations below (and on the individual |
| 64 | * methods) are central to the definition of this service. They are used in |
| 65 | * place of XML configuration files (though the XML deployment descriptors, as |
| 66 | * they are called, can be used to override the annotations), and will influence |
| 67 | */ |
| 68 | // ~ Service annotations |
| 69 | // ============================================================================= |
| 70 | /* |
| 71 | * Source: EJB3 Specification Purpose: Prevents the Container from managing |
| 72 | * transactions (CMT), and instead delegates commits and rollbacks to user code. |
| 73 | * This is, however, managed by Spring (@Transactional below) |
| 74 | * |
| 75 | * @see https://trac.openmicroscopy.org.uk/omero/ticket/427 |
| 76 | */ |
| 77 | @TransactionManagement(TransactionManagementType.BEAN) |
| 78 | /* |
| 79 | * Source: Spring Purpose: Used by EventHandler#checkReadyOnly(MethodInvocation) |
| 80 | * to deteremine if a method is read-only. No annotation implies ready-only, so |
| 81 | * it is essential to have this annotation on all write methods. |
| 82 | * |
| 83 | * Only non-container annotation and is a superset of EJB3's |
| 84 | * @TransactionAttribute. Currently, suffices for our TX needs, but we may |
| 85 | * eventually have to provide both annotations or to switch to the EJB3 spec |
| 86 | * annotations and write a new TX-interceptor for Spring. |
| 87 | * |
| 88 | * @see http://www.interface21.com/pitchfork Project Pitchfork. |
| 89 | */ |
| 90 | @Transactional |
| 91 | /* |
| 92 | * Source: EJB3 Specification Purpose: Marks this service as stateless, which |
| 93 | * means that instances can be created as needed and given to any client. |
| 94 | * Concurrent calls are permitted though they may be routed to different |
| 95 | * servers. The stateful counterpart is simply @Stateful, but it imposes several |
| 96 | * restrictions on the class, e.g. that all fields must be transient or |
| 97 | * serializable. On the other hand, all fields for @Stateless instances must be |
| 98 | * thread-safe, with no state being obviously thread-safetest. |
| 99 | * |
| 100 | * @see https://trac.openmicroscopy.org.uk/omero/ticket/173 |
| 101 | */ |
| 102 | @Stateless |
| 103 | /* |
| 104 | * Source: EJB3 Specification Purpose: Defines which interface will be |
| 105 | * represented to remote clients of this service. |
| 106 | */ |
| 107 | @Remote(IConfig.class) |
| 108 | /* |
| 109 | * Source: JBoss-speciifc Purpose: Defines a non-standard name for looking up |
| 110 | * this service. During the early days of the EJB3 spec, the default value kept |
| 111 | * changing and so it was easier to define our own. This is also somewhat |
| 112 | * memorable in comparison to "[earFile]/[ejbName]/remote", however, this |
| 113 | * doesn't allow Omero to be deployed multiple times in a single server. |
| 114 | * |
| 115 | * The second remote binding annotation permits transport over a secure |
| 116 | * protocol. For more information on enabling this transport, see |
| 117 | * |
| 118 | * https://trac.openmicroscopy.org.uk/omero/wiki/OmeroSecurity |
| 119 | * |
| 120 | */ |
| 121 | @RemoteBindings({ |
| 122 | @RemoteBinding(jndiBinding = "omero/remote/ome.api.IConfig"), |
| 123 | @RemoteBinding(jndiBinding = "omero/secure/ome.api.IConfig", |
| 124 | clientBindUrl="sslsocket://0.0.0.0:3843") |
| 125 | }) |
| 126 | /* |
| 127 | * Source: EJB3 Specification Purpose: Defines which interface will be |
| 128 | * represented to remote clients of this service. There need be no relationship |
| 129 | * between this interface and the @Remote interface. Currently unused, since |
| 130 | * services don't look up dependencies from JNDI but rather have them injected |
| 131 | * by Spring. |
| 132 | */ |
| 133 | @Local(IConfig.class) |
| 134 | /* |
| 135 | * Source: JBoss-specific Purpose: See @RemoteBinding. |
| 136 | */ |
| 137 | @LocalBinding(jndiBinding = "omero/local/ome.api.IConfig") |
| 138 | /* |
| 139 | * Source: EJB3 Specification Purpose: List of classes (with no-arg |
| 140 | * constructors) which should serve as interceptors for all calls to this class. |
| 141 | * Available interceptors are: |
| 142 | * |
| 143 | * @AroundInvoke (interceptor - around every method call) @PostConstruct |
| 144 | * (callback - after initialization) @PreDestroy (callback - before dropping |
| 145 | * this instance) |
| 146 | * |
| 147 | * For @Stateful services there are also: @PostActivate (callback - after the |
| 148 | * instance is deserialized) @PrePassivate (callback - before the instance is |
| 149 | * serialized) |
| 150 | * |
| 151 | * The SimpleLifecycle does the minimum (calls create() after init and destroy() |
| 152 | * before destruction) and saves a good deal of extra typing. This can also be |
| 153 | * achieved by inheritance (i.e. AbstractBean.create() could be marked |
| 154 | * @PostConstruct); however, only one class in an inheritance hierarchy can be |
| 155 | * marked with callbacks, and this is overly restrictive for us. |
| 156 | * |
| 157 | * OmeroAroundInvoke applies the OMERO security model to every method |
| 158 | * invocation as well as applying the list of compile-time determined |
| 159 | * HardWiredInterceptors. All of this functionality should be trangential |
| 160 | * to the functioning of the services *server-side*. |
| 161 | */ |
| 162 | @Interceptors( { OmeroAroundInvoke.class, SimpleLifecycle.class }) |
| 163 | /* |
| 164 | * Stateful differences: -------------------- @Cache(NoPassivationCache.class) -- |
| 165 | * JBoss-specific Purpose: can be used to turn off passivation |
| 166 | */ |
| 167 | public class ConfigImpl extends AbstractLevel2Service implements IConfig { |
| 168 | |
| 169 | /* |
| 170 | * Stateful differences: -------------------- A stateful service must be |
| 171 | * marked as Serializable and all fields must be either marked transient, be |
| 172 | * serializable themselves, or be set to null before serialization. Here |
| 173 | * we've marked the jdbc field as transient out of habit. |
| 174 | * |
| 175 | * @see https://trac.openmicroscopy.org.uk/omero/ticket/173 |
| 176 | */ |
| 177 | private transient SimpleJdbcTemplate jdbc; |
| 178 | |
| 179 | /** |
| 180 | * {@link SimpleJdbcTemplate} setter for dependency injection. |
| 181 | * |
| 182 | * @param jdbcTemplate |
| 183 | * @see ome.services.util.BeanHelper#throwIfAlreadySet(Object, Object) |
| 184 | */ |
| 185 | /* |
| 186 | * Developer notes: --------------- Because of the complicated lifecycle of |
| 187 | * EJBs it is not possible to fully configure them with constructor |
| 188 | * injection (which is safer). Instead, we have to provide public setters |
| 189 | * for all properties which need to be injected. And since Java doesn't have |
| 190 | * the concept of "friends" (yet), this opens up our classes for some weird |
| 191 | * manipulations. Therefore we've made all bean setters "final" and added a |
| 192 | * call to "throwIfAlreadySet" which will only allow previously null fields |
| 193 | * to be set. |
| 194 | */ |
| 195 | public final void setJdbcTemplate(SimpleJdbcTemplate jdbcTemplate) { |
| 196 | getBeanHelper().throwIfAlreadySet(jdbc, jdbcTemplate); |
| 197 | this.jdbc = jdbcTemplate; |
| 198 | } |
| 199 | |
| 200 | /* |
| 201 | * Developer notes: --------------- This method provides the lookup value |
| 202 | * needed for finding services within the Spring context and, by convention, |
| 203 | * the value which is to be returned can be found in the file |
| 204 | * "ome/services/service-<class name>.xml" |
| 205 | */ |
| 206 | public final Class<? extends ServiceInterface> getServiceInterface() { |
| 207 | return IConfig.class; |
| 208 | } |
| 209 | |
| 210 | // ~ Service methods |
| 211 | // ========================================================================= |
| 212 | |
| 213 | /* |
| 214 | * Source: EJB3 Specification Purpose: defines the role which must have been |
| 215 | * obtained during authentication and authorization in order to access this |
| 216 | * method. This works in combination with the BasicMethodSecurity to fully |
| 217 | * define security semantics. |
| 218 | */ |
| 219 | /** |
| 220 | * see {@link IConfig#getServerTime()} |
| 221 | */ |
| 222 | @RolesAllowed("user") |
| 223 | public Date getServerTime() { |
| 224 | return new Date(); |
| 225 | } |
| 226 | |
| 227 | /** |
| 228 | * see {@link IConfig#getDatabaseTime()} |
| 229 | */ |
| 230 | @RolesAllowed("user") |
| 231 | // see above |
| 232 | public Date getDatabaseTime() { |
| 233 | Date date = jdbc.queryForObject("select now()", Date.class); |
| 234 | return date; |
| 235 | } |
| 236 | |
| 237 | /** |
| 238 | * see {@link IConfig#getConfigValue(String)} |
| 239 | */ |
| 240 | @RolesAllowed("user") |
| 241 | // see above |
| 242 | public String getConfigValue(String key) { |
| 243 | return null; |
| 244 | } |
| 245 | |
| 246 | /** |
| 247 | * see {@link IConfig#setConfigValue(String, String)} |
| 248 | */ |
| 249 | @RolesAllowed("system") |
| 250 | // see above |
| 251 | public void setConfigValue(String key, String value) { |
| 252 | return; |
| 253 | } |
| 254 | |
| 255 | /** |
| 256 | * see {@link IConfig#getVersion()} |
| 257 | */ |
| 258 | @RolesAllowed("user") |
| 259 | // see above |
| 260 | public String getVersion() { |
| 261 | return Version.OMERO; |
| 262 | } |
| 263 | |
| 264 | } |
Note: See TracBrowser
for help on using the browser.
