Changeset 1024
- Timestamp:
- 10/09/06 15:25:26 (2 years ago)
- Location:
- trunk/components
- Files:
-
- 1 removed
- 4 modified
-
common/src/omeis/providers/re/RenderingEngine.java (modified) (2 diffs)
-
rendering/src/omeis/providers/re/RenderingEngineImpl.java (deleted)
-
server/resources/ome/services/service-ome.api.IThumb.xml (modified) (1 diff)
-
server/resources/ome/services/service-omeis.providers.re.RenderingEngine.xml (modified) (2 diffs)
-
server/src/ome/services/RenderingBean.java (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/components/common/src/omeis/providers/re/RenderingEngine.java
r862 r1024 43 43 import ome.model.enums.Family; 44 44 import ome.model.enums.RenderingModel; 45 import ome.model.meta.Event; 46 import ome.system.EventContext; 45 47 import ome.system.SelfConfigurableService; 46 48 import omeis.providers.re.codomain.CodomainMapContext; … … 115 117 public void load(); 116 118 119 /** Returns the current {@link EventContext} for this instance. This is 120 * useful for later identifying changes made by this {@link Event}. 121 */ 122 public EventContext getCurrentEventContext(); 123 117 124 /** 118 125 * Specifies the model that dictates how transformed raw data has to be -
trunk/components/server/resources/ome/services/service-ome.api.IThumb.xml
r966 r1024 38 38 <bean parent="level2" id="internal:ome.api.IThumb" class="ome.logic.ThumbImpl"> 39 39 <property name="ioService" ref="/OME/OMEIS/Thumbs"/> 40 <property name="renderingEngine" ref="internal:ome .services.RenderingWrapper"/>40 <property name="renderingEngine" ref="internal:omeis.providers.re.RenderingEngine"/> 41 41 <property name="scaleService" ref="internal:ome.api.IScale"/> 42 42 </bean> -
trunk/components/server/resources/ome/services/service-omeis.providers.re.RenderingEngine.xml
r903 r1024 36 36 <beans> 37 37 38 <bean singleton="false" parent=" binary"38 <bean singleton="false" parent="level2" 39 39 id="internal:omeis.providers.re.RenderingEngine" 40 class="omeis.providers.re.RenderingEngineImpl"> 40 class="ome.services.RenderingBean"> 41 <!-- following copied from parent="binary" --> 42 <property name="pixelsMetadata" ref="internal:ome.api.IPixels"/> 43 <property name="pixelsData" ref="/OME/OMEIS/Pixels"/> 41 44 </bean> 42 45 … … 46 49 </bean> 47 50 48 <bean singleton="false" parent="level2"49 id="internal:ome.services.RenderingWrapper"50 class="ome.services.RenderingBean">51 <property name="delegate" ref="internal:omeis.providers.re.RenderingEngine"/>52 </bean>53 54 <bean id="managed:ome.services.RenderingWrapper" parent="managedService">55 <property name="proxyInterfaces" value="ome.services.RenderingWrapper"/>56 <property name="target" ref="internal:omeis.providers.re.RenderingEngine"/>57 </bean>58 51 </beans> -
trunk/components/server/src/ome/services/RenderingBean.java
r922 r1024 31 31 32 32 // Java imports 33 import java.io.IOException; 33 34 import java.io.Serializable; 34 35 import java.util.ArrayList; 35 36 import java.util.List; 37 import java.util.concurrent.locks.ReentrantReadWriteLock; 36 38 37 39 import javax.annotation.PostConstruct; … … 48 50 49 51 // Third-party libraries 52 import org.apache.commons.logging.Log; 53 import org.apache.commons.logging.LogFactory; 50 54 import org.jboss.annotation.ejb.LocalBinding; 51 55 import org.jboss.annotation.ejb.RemoteBinding; … … 53 57 import org.jboss.annotation.security.SecurityDomain; 54 58 import org.jboss.ejb3.cache.NoPassivationCache; 59 import org.springframework.transaction.annotation.Transactional; 55 60 56 61 // Application-internal dependencies 57 62 import ome.annotations.RevisionDate; 58 63 import ome.annotations.RevisionNumber; 64 import ome.api.IPixels; 59 65 import ome.api.ServiceInterface; 66 import ome.conditions.ApiUsageException; 67 import ome.conditions.InternalException; 68 import ome.conditions.ResourceError; 69 import ome.conditions.ValidationException; 70 import ome.io.nio.PixelBuffer; 71 import ome.io.nio.PixelsService; 60 72 import ome.logic.AbstractLevel2Service; 61 73 import ome.model.IObject; 62 74 import ome.model.core.Channel; 63 75 import ome.model.core.Pixels; 76 import ome.model.display.ChannelBinding; 64 77 import ome.model.display.QuantumDef; 78 import ome.model.display.RenderingDef; 65 79 import ome.model.enums.Family; 66 80 import ome.model.enums.RenderingModel; 81 import ome.system.EventContext; 82 import ome.system.SimpleEventContext; 67 83 import ome.util.ShallowCopy; 68 84 69 85 import omeis.providers.re.RGBBuffer; 86 import omeis.providers.re.Renderer; 70 87 import omeis.providers.re.RenderingEngine; 71 import omeis.providers.re.RenderingEngineImpl;72 88 import omeis.providers.re.codomain.CodomainMapContext; 73 89 import omeis.providers.re.data.PlaneDef; 74 75 interface RenderingWrapper extends RenderingEngine {} 90 import omeis.providers.re.quantum.QuantizationException; 76 91 77 92 /** 78 * Provides the {@link RenderingEngine} service. This class is a serializable 79 * wrapper around {@link RenderingEngineImpl}. 93 * Provides the {@link RenderingEngine} service. This class is an Adapter to 94 * wrap the {@link Renderer} so to make it thread-safe. 95 * <p> 96 * The multi-threaded design of this component is based on dynamic locking and 97 * confinement techiniques. All access to the component's internal parts happens 98 * through a <code>RenderingEngineImpl</code> object, which is fully 99 * synchronized. Internal parts are either never leaked out or given away only 100 * if read-only objects. (The only exception are the {@link CodomainMapContext} 101 * objects which are not read-only but are copied upon every method invocation 102 * so to maintain safety.) 103 * </p> 104 * <p> 105 * Finally the {@link RenderingEngine} component doesn't make use of constructs 106 * that could compromise liveness. 107 * </p> 80 108 * 81 * @author Josh Moore, josh.moore at gmx.de 109 * @author Jean-Marie Burel <a 110 * href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> 111 * @author <br> 112 * Andrea Falconi <a 113 * href="mailto:a.falconi@dundee.ac.uk"> a.falconi@dundee.ac.uk</a> 114 * @version 2.2 <small> (<b>Internal version:</b> $Revision: 1.4 $ $Date: 115 * 2005/07/05 16:13:52 $) </small> 116 * @since OME2.2 117 * @author Andrea Falconi, a.falconi at dundee.ac.uk 118 * @author Chris Allan, callan at blackcat.ca 119 * @author Jean-Marie Burel, j.burel at dundee.ac.uk 120 * @author Josh Moore, josh.moore at gmx.de 82 121 * @version $Revision$, $Date$ 83 * @since 3.0-M3 122 * @see RenderingEngine 123 * @since 3.0-M3 84 124 */ 85 125 @RevisionDate("$Date$") 86 126 @RevisionNumber("$Revision$") 127 87 128 @Stateful 88 129 @Remote(RenderingEngine.class) … … 92 133 @SecurityDomain("OmeroSecurity") 93 134 @Cache(NoPassivationCache.class) 135 @Transactional // TODO previously not here. examine the difference. 94 136 public class RenderingBean extends AbstractLevel2Service 95 implements Rendering Wrapper, Serializable137 implements RenderingEngine, Serializable 96 138 { 97 139 98 private static final long serialVersionUID = -4383698215540637038L; 99 100 private transient RenderingEngine delegate; 101 102 public final void setDelegate(RenderingEngine delegate) { 103 throwIfAlreadySet(this.delegate, delegate); 104 this.delegate = delegate; 105 } 140 private static final long serialVersionUID = -4383698215540637039L; 141 142 private static final Log log = LogFactory.getLog(RenderingBean.class); 106 143 107 144 @Override 108 145 protected Class<? extends ServiceInterface> getServiceInterface() { 109 return RenderingWrapper.class; 146 return RenderingEngine.class; 147 } 148 149 // ~ State 150 // ========================================================================= 151 152 /* 153 * LIFECYCLE: 154 * 1. new() || new(Services[]) 155 * 2. (lookupX || useX)+ && load 156 * 3. call methods 157 * 4. optionally: return to 2. 158 * 5. destroy() 159 * 160 * TODO: when a setXXX() method is called, when do I reload? always? 161 * or ondirty? 162 */ 163 164 /** 165 * Transforms the raw data. Entry point to the unsych parts of the component. 166 * As soon as Renderer is not null, the Engine is ready to use. 167 */ 168 private transient Renderer renderer; 169 170 /** The pixels set to the rendering engine is for. */ 171 private transient Pixels pixelsObj; 172 173 /** The rendering settings associated to the pixels set. */ 174 private transient RenderingDef rendDefObj; 175 176 /** Reference to the service used to retrieve the pixels data. */ 177 private transient PixelsService pixDataSrv; 178 179 /** Reference to the service used to retrieve the pixels metadata. */ 180 private transient IPixels pixMetaSrv; 181 182 /** read-write lock to prevent READ-calls during WRITE operations. Unneeded 183 * for remote invocations (EJB synchronizes). 184 */ 185 private transient ReentrantReadWriteLock rwl 186 = new ReentrantReadWriteLock(); 187 188 /** set injector. For use during configuration. Can only be called once. */ 189 public void setPixelsMetadata(IPixels metaService) 190 { 191 this.throwIfAlreadySet(this.pixMetaSrv, metaService); 192 pixMetaSrv = metaService; 193 } 194 195 /** set injector. For use during configuration. Can only be called once. */ 196 public void setPixelsData(PixelsService dataService) 197 { 198 throwIfAlreadySet(this.pixDataSrv, dataService); 199 pixDataSrv = dataService; 110 200 } 111 201 … … 113 203 // ========================================================================= 114 204 205 /** lifecycle method -- {@link PostActivate} and {@link PostConstruct}. 206 * Delegates to super class */ 115 207 @PostActivate 116 208 @PostConstruct 209 @Override 117 210 public void create() 118 211 { … … 120 213 } 121 214 215 /** lifecycle method -- {@link PrePassivate}. Disallows all passivation. */ 122 216 @PrePassivate 123 217 public void passivate() … … 126 220 } 127 221 222 /** lifecycle method -- {@link PreDestroy}. Nulls {@link Renderer} instance 223 * and delegates to super class with {@link ReentrantReadWriteLock write lock} 224 */ 128 225 @PreDestroy 226 @Override 129 227 public void destroy() 130 228 { 131 super.destroy(); 132 delegate = null; 133 } 134 135 // ~ DELEGATION 136 // ========================================================================= 137 229 rwl.writeLock().lock(); 230 231 try { 232 renderer = null; // marks as unready. all other state is marked transient. 233 super.destroy(); 234 } finally { 235 rwl.writeLock().unlock(); 236 } 237 } 238 239 /* 240 * SETTERS for use in dependency injection. All invalidate the current 241 * renderer. Only possible with the WriteLock so no possibility of 242 * corrupting data. 243 * 244 * a.k.a. STATE-MANAGEMENT 245 */ 246 247 /** 248 * Implemented as specified by the {@link RenderingEngine} interface. 249 * @see RenderingEngine#lookupPixels(long) 250 */ 138 251 @RolesAllowed("user") 139 252 @TransactionAttribute(REQUIRED) 140 public void lookupPixels(long arg0) 141 { 142 delegate.lookupPixels(arg0); 143 } 144 253 public void lookupPixels(long pixelsId) 254 { 255 rwl.writeLock().lock(); 256 257 try { 258 259 this.pixelsObj = pixMetaSrv.retrievePixDescription(pixelsId); 260 this.renderer = null; 261 262 if ( pixelsObj == null ) 263 throw new ValidationException( 264 "Pixels object with id "+pixelsId+" not found."); 265 266 } finally { 267 rwl.writeLock().unlock(); 268 } 269 270 if (log.isDebugEnabled()) 271 log.debug("lookupPixels for id "+pixelsId+" succeeded: "+this.pixelsObj); 272 } 273 274 /** 275 * Implemented as specified by the {@link RenderingEngine} interface. 276 * @see RenderingEngine#lookupRenderingDef(long) 277 */ 145 278 @RolesAllowed("user") 146 279 @TransactionAttribute(REQUIRED) 147 public void lookupRenderingDef(long arg0) 148 { 149 delegate.lookupRenderingDef(arg0); 150 } 151 280 public void lookupRenderingDef(long pixelsId) 281 { 282 rwl.writeLock().lock(); 283 284 try { 285 this.rendDefObj = pixMetaSrv.retrieveRndSettings(pixelsId); 286 this.renderer = null; 287 288 if ( rendDefObj == null ) 289 throw new ValidationException( 290 "RenderingDef for Pixels="+pixelsId+" not found."); 291 } finally { 292 rwl.writeLock().unlock(); 293 } 294 295 if (log.isDebugEnabled()) 296 log.debug("lookupRenderingDef for Pixels="+pixelsId+" succeeded: "+this.rendDefObj); 297 298 } 299 300 /** 301 * Implemented as specified by the {@link RenderingEngine} interface. 302 * @see RenderingEngine#load() 303 */ 152 304 @RolesAllowed("user") 153 305 @TransactionAttribute(REQUIRED) 154 306 public void load() 155 307 { 156 delegate.load(); 157 } 158 159 // ------------------------------------------------------------------------- 160 161 @RolesAllowed("user") 162 public RGBBuffer render(PlaneDef arg0) 163 { 164 return delegate.render(arg0); 165 } 166 167 // ------------------------------------------------------------------------- 168 308 rwl.writeLock().lock(); 309 310 try { 311 312 errorIfNullPixels(); 313 314 /* 315 * TODO we could also allow for setting of the buffer! perhaps 316 * better caching, etc. 317 */ 318 PixelBuffer buffer = pixDataSrv.getPixelBuffer(pixelsObj); 319 320 renderer = new Renderer(pixMetaSrv, pixelsObj, rendDefObj, buffer); 321 } finally { 322 rwl.writeLock().unlock(); 323 } 324 } 325 326 /** Implemented as specified by the {@link RenderingEngine} interface. TODO 327 * @see RenderingEngine#getCurrentEventContext() 328 */ 329 @RolesAllowed("user") 330 @TransactionAttribute(REQUIRED) 331 public EventContext getCurrentEventContext() 332 { 333 return new SimpleEventContext( getSecuritySystem().getEventContext() ); 334 } 335 336 /* 337 * DELEGATING METHODS ================================================== 338 * 339 * All following methods follow the pattern: 340 * 1) get read or write lock 341 * try { 342 * 2) error on null 343 * 3) delegate method to renderer/renderingObj/pixelsObj 344 * } finally { 345 * 4) release lock 346 * } 347 * 348 * TODO for all of these methods it would be good to have an 349 * interceptor to check for a null renderer value. 350 * would have to be JBoss specific 351 * or apply at the Renderer level 352 * or this would have to be a delegate to REngine to Renderer! 353 * 354 * @Write || @Read on each. 355 * for example 356 * see http://www.onjava.com/pub/a/onjava/2004/08/25/aoa.html?page=3 357 * for asynch. annotations (also @TxSynchronized) 358 * 359 */ 360 361 /** 362 * Implemented as specified by the {@link RenderingEngine} interface. 363 * @see RenderingEngine#render(PlaneDef) 364 */ 365 @RolesAllowed("user") 366 public RGBBuffer render(PlaneDef pd) 367 throws ResourceError, ValidationException 368 { 369 rwl.readLock().lock(); 370 371 try { 372 errorIfInvalidState(); 373 return renderer.render(pd); 374 } catch (IOException e) { 375 ResourceError re = new ResourceError( 376 "IO error while rendering:\n"+e.getMessage()); 377 re.initCause(e); 378 throw re; 379 } catch (QuantizationException e) { 380 InternalException ie = new InternalException( 381 "QuantizationException while rendering:\n"+e.getMessage()); 382 ie.initCause(e); 383 throw ie; 384 } finally { 385 rwl.readLock().unlock(); 386 } 387 } 388 389 // ~ Settings 390 // ========================================================================= 391 392 /** 393 * Implemented as specified by the {@link RenderingEngine} interface. 394 * @see RenderingEngine#resetDefaults() 395 */ 169 396 @RolesAllowed("user") 170 397 public void resetDefaults() 171 398 { 172 delegate.resetDefaults(); 173 } 174 399 rwl.writeLock().lock(); 400 401 try { 402 errorIfInvalidState(); 403 renderer.resetDefaults(); 404 } finally { 405 rwl.writeLock().unlock(); 406 } 407 } 408 409 /** 410 * Implemented as specified by the {@link RenderingEngine} interface. 411 * @see RenderingEngine#saveCurrentSettings() 412 */ 175 413 @RolesAllowed("user") 176 414 public void saveCurrentSettings() 177 415 { 178 delegate.saveCurrentSettings(); 416 rwl.writeLock().lock(); 417 418 try { 419 errorIfNullRenderingDef(); 420 pixMetaSrv.saveRndSettings(rendDefObj); 421 } finally { 422 rwl.writeLock().unlock(); 423 } 179 424 iUpdate.flush(); 180 425 iUpdate.commit(); 181 426 } 182 427 183 // ------------------------------------------------------------------------- 184 185 @RolesAllowed("user") 186 public double getChannelCurveCoefficient(int arg0) 187 { 188 return delegate.getChannelCurveCoefficient(arg0); 189 } 190 191 @RolesAllowed("user") 192 public Family getChannelFamily(int arg0) 193 { 194 Family family = delegate.getChannelFamily(arg0); 195 return copyFamily(family); 196 } 197 198 @RolesAllowed("user") 199 public boolean getChannelNoiseReduction(int arg0) 200 { 201 return delegate.getChannelNoiseReduction(arg0); 202 } 203 204 @RolesAllowed("user") 205 public double[] getChannelStats(int arg0) 206 { 207 return delegate.getChannelStats(arg0); 208 } 209 210 @RolesAllowed("user") 211 public double getChannelWindowEnd(int arg0) 212 { 213 return delegate.getChannelWindowEnd(arg0); 214 } 215 216 @RolesAllowed("user") 217 public double getChannelWindowStart(int arg0) 218 { 219 return delegate.getChannelWindowStart(arg0); 220 } 221 428 // ~ Renderer Delegation (READ) 429 // ========================================================================= 430 431 /** 432 * Implemented as specified by the {@link RenderingEngine} interface. 433 * @see RenderingEngine#getChannelCurveCoefficient(int) 434 */ 435 @RolesAllowed("user") 436 public double getChannelCurveCoefficient(int w) 437 { 438 rwl.readLock().lock(); 439 440 try { 441 errorIfInvalidState(); 442 ChannelBinding[] cb = renderer.getChannelBindings(); 443 return cb[w].getCoefficient().doubleValue(); 444 } finally { 445 rwl.readLock().unlock(); 446 } 447 } 448 449 /** 450 * Implemented as specified by the {@link RenderingEngine} interface. 451 * @see RenderingEngine#getChannelFamily(int) 452 */ 453 @RolesAllowed("user") 454 public Family getChannelFamily(int w) 455 { 456 rwl.readLock().lock(); 457 458 try { 459 errorIfInvalidState(); 460 ChannelBinding[] cb = renderer.getChannelBindings(); 461 Family family = cb[w].getFamily(); 462 return copyFamily(family); 463 } finally { 464 rwl.readLock().unlock(); 465 } 466 } 467 468 /** 469 * Implemented as specified by the {@link RenderingEngine} interface. 470 * @see RenderingEngine#getChannelNoiseReduction(int) 471 */ 472 @RolesAllowed("user") 473 public boolean getChannelNoiseReduction(int w) 474 { 475 rwl.readLock().lock(); 476 477 try { 478 errorIfInvalidState(); 479 ChannelBinding[] cb = renderer.getChannelBindings(); 480 return cb[w].getNoiseReduction().booleanValue(); 481 } finally { 482 rwl.readLock().unlock(); 483 } 484 } 485 486 /** Implemented as specified by the {@link RenderingEngine} interface. */ 487 @RolesAllowed("user") 488 public double[] getChannelStats(int w) 489 { 490 rwl.readLock().lock(); 491 492 try { 493 errorIfInvalidState(); 494 // ChannelBinding[] cb = renderer.getChannelBindings(); 495 // FIXME 496 // double[] stats = cb[w].getStats(), copy = new double[stats.length]; 497 // System.arraycopy(stats, 0, copy, 0, stats.length); 498 return null; 499 } finally { 500 rwl.readLock().unlock(); 501 }// FIXME copy; 502 // NOTE: These stats are supposed to be read-only; however we make a 503 // copy to be on the safe side. 504 } 505 506 /** 507 * Implemented as specified by the {@link RenderingEngine} interface. 508 * @see RenderingEngine#getChannelWindowEnd(int) 509 */ 510 @RolesAllowed("user") 511 public double getChannelWindowEnd(int w) 512 { 513 rwl.readLock().lock(); 514 515 try { 516 errorIfInvalidState(); 517 ChannelBinding[] cb = renderer.getChannelBindings(); 518 return cb[w].getInputEnd().intValue(); 519 } finally { 520 rwl.readLock().unlock(); 521 } 522 } 523 524 /** 525 * Implemented as specified by the {@link RenderingEngine} interface. 526 * @see RenderingEngine#getChannelWindowStart(int) 527 */ 528 @RolesAllowed("user") 529 public double getChannelWindowStart(int w) 530 { 531 rwl.readLock().lock(); 532 533 try { 534 errorIfInvalidState(); 535 ChannelBinding[] cb = renderer.getChannelBindings(); 536 return cb[w].getInputStart().intValue(); 537 } finally { 538 rwl.readLock().unlock(); 539 } 540 } 541 542 /** 543 * Implemented as specified by the {@link RenderingEngine} interface. 544 * @see RenderingEngine#getRGBA(int) 545 */ 546 @RolesAllowed("user") 547 public int[] getRGBA(int w) 548 { 549 550 rwl.readLock().lock(); 551 552 try { 553 errorIfInvalidState(); 554 int[] rgba = new int[4]; 555 ChannelBinding[] cb = renderer.getChannelBindings(); 556 // NOTE: The rgba is supposed to be read-only; however we make a 557 // copy to be on the safe side. 558 rgba[0] = cb[w].getColor().getRed().intValue(); 559 rgba[1] = cb[w].getColor().getGreen().intValue(); 560 rgba[2] = cb[w].getColor().getBlue().intValue(); 561 rgba[3] = cb[w].getColor().getAlpha().intValue(); 562 return rgba; 563 } finally { 564 rwl.readLock().unlock(); 565 } 566 } 567 568 /** 569 * Implemented as specified by the {@link RenderingEngine} interface. 570 * @see RenderingEngine#isActive(int) 571 */ 572 @RolesAllowed("user") 573 public boolean isActive(int w) 574 { 575 rwl.readLock().lock(); 576
