001 // SECTION-START[License Header] 002 // <editor-fold defaultstate="collapsed" desc=" Generated License "> 003 /* 004 * Java Object Management and Configuration 005 * Copyright (C) Christian Schulte, 2011-313 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions 010 * are met: 011 * 012 * o Redistributions of source code must retain the above copyright 013 * notice, this list of conditions and the following disclaimer. 014 * 015 * o Redistributions in binary form must reproduce the above copyright 016 * notice, this list of conditions and the following disclaimer in 017 * the documentation and/or other materials provided with the 018 * distribution. 019 * 020 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 021 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 022 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 023 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 024 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 025 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 026 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 027 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 029 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 * 031 * $JOMC: RuntimeImplementations.java 4381 2012-03-04 19:29:29Z schulte2005 $ 032 * 033 */ 034 // </editor-fold> 035 // SECTION-END 036 package org.jomc.ri.model; 037 038 import java.util.Map; 039 import javax.xml.bind.annotation.XmlTransient; 040 import org.jomc.model.Implementation; 041 import org.jomc.model.ImplementationReference; 042 import org.jomc.model.Implementations; 043 import static org.jomc.ri.model.RuntimeModelObjects.createMap; 044 045 // SECTION-START[Documentation] 046 // <editor-fold defaultstate="collapsed" desc=" Generated Documentation "> 047 /** 048 * Runtime {@code Implementations}. 049 * 050 * <dl> 051 * <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeImplementations</dd> 052 * <dt><b>Name:</b></dt><dd>JOMC RI RuntimeImplementations</dd> 053 * <dt><b>Specifications:</b></dt> 054 * <dd>org.jomc.ri.model.RuntimeModelObject @ 1.2</dd> 055 * <dt><b>Abstract:</b></dt><dd>No</dd> 056 * <dt><b>Final:</b></dt><dd>No</dd> 057 * <dt><b>Stateless:</b></dt><dd>No</dd> 058 * </dl> 059 * 060 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.2 061 * @version 1.2 062 */ 063 // </editor-fold> 064 // SECTION-END 065 // SECTION-START[Annotations] 066 // <editor-fold defaultstate="collapsed" desc=" Generated Annotations "> 067 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" ) 068 // </editor-fold> 069 // SECTION-END 070 public class RuntimeImplementations extends Implementations implements RuntimeModelObject 071 { 072 // SECTION-START[RuntimeImplementations] 073 074 /** Cache map. */ 075 @XmlTransient 076 private transient final Map<String, Implementation> implementationsByIdentifierCache = createMap(); 077 078 /** Cache map. */ 079 @XmlTransient 080 private transient final Map<String, Implementation> implementationsByClassCache = createMap(); 081 082 /** Cache map. */ 083 @XmlTransient 084 private transient final Map<String, Implementation> implementationsByNameCache = createMap(); 085 086 /** Cache map. */ 087 @XmlTransient 088 private transient final Map<String, ImplementationReference> referencesByIdentifierCache = createMap(); 089 090 /** 091 * Creates a new {@code RuntimeImplementations} instance by deeply copying a given {@code Implementations} instance. 092 * 093 * @param implementations The instance to copy. 094 * 095 * @throws NullPointerException if {@code implementations} is {@code null}. 096 */ 097 public RuntimeImplementations( final Implementations implementations ) 098 { 099 super( implementations ); 100 101 if ( this.getAuthors() != null ) 102 { 103 this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) ); 104 } 105 if ( this.getDocumentation() != null ) 106 { 107 this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) ); 108 } 109 110 this.copyImplementations(); 111 this.copyImplementationReferences(); 112 } 113 114 /** 115 * Gets an implementation for a given identifier from the list of implementations. 116 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 117 * cached result object is available, this method queries the super-class for a result object to return and caches 118 * the outcome of that query for use on successive calls.</p> 119 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 120 * state of the instance, should the state of the instance change.</p> 121 * 122 * @param implementation The identifier of the implementation to return. 123 * 124 * @return The first matching implementation or {@code null}, if no such implementation is found. 125 * 126 * @throws NullPointerException if {@code implementation} is {@code null}. 127 * 128 * @see #getImplementation() 129 * @see Implementation#getIdentifier() 130 * @see #clear() 131 */ 132 @Override 133 public Implementation getImplementation( final String implementation ) 134 { 135 if ( implementation == null ) 136 { 137 throw new NullPointerException( "implementation" ); 138 } 139 140 synchronized ( this.implementationsByIdentifierCache ) 141 { 142 Implementation i = this.implementationsByIdentifierCache.get( implementation ); 143 144 if ( i == null && !this.implementationsByIdentifierCache.containsKey( implementation ) ) 145 { 146 i = super.getImplementation( implementation ); 147 this.implementationsByIdentifierCache.put( implementation, i ); 148 } 149 150 return i; 151 } 152 } 153 154 /** 155 * Gets an implementation for a given class from the list of implementations. 156 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 157 * cached result object is available, this method queries the super-class for a result object to return and caches 158 * the outcome of that query for use on successive calls.</p> 159 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 160 * state of the instance, should the state of the instance change.</p> 161 * 162 * @param implementation The class of the implementation to return. 163 * 164 * @return The first matching implementation or {@code null}, if no such implementation is found. 165 * 166 * @throws NullPointerException if {@code implementation} is {@code null}. 167 * 168 * @see #getImplementation() 169 * @see Implementation#isClassDeclaration() 170 * @see Implementation#getClazz() 171 * @see #clear() 172 */ 173 @Override 174 public Implementation getImplementation( final Class<?> implementation ) 175 { 176 if ( implementation == null ) 177 { 178 throw new NullPointerException( "implementation" ); 179 } 180 181 synchronized ( this.implementationsByClassCache ) 182 { 183 Implementation i = this.implementationsByClassCache.get( implementation.getName() ); 184 185 if ( i == null && !this.implementationsByClassCache.containsKey( implementation.getName() ) ) 186 { 187 i = super.getImplementation( implementation ); 188 this.implementationsByClassCache.put( implementation.getName(), i ); 189 } 190 191 return i; 192 } 193 } 194 195 /** 196 * Gets an implementation for a given name from the list of implementations. 197 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 198 * cached result object is available, this method queries the super-class for a result object to return and caches 199 * the outcome of that query for use on successive calls.</p> 200 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 201 * state of the instance, should the state of the instance change.</p> 202 * 203 * @param name The name of the implementation to return. 204 * 205 * @return The first matching implementation or {@code null}, if no such implementation is found. 206 * 207 * @throws NullPointerException if {@code name} is {@code null}. 208 * 209 * @see #getImplementation() 210 * @see Implementation#getName() 211 * @see #clear() 212 */ 213 @Override 214 public Implementation getImplementationByName( final String name ) 215 { 216 if ( name == null ) 217 { 218 throw new NullPointerException( "name" ); 219 } 220 221 synchronized ( this.implementationsByNameCache ) 222 { 223 Implementation i = this.implementationsByNameCache.get( name ); 224 225 if ( i == null && !this.implementationsByNameCache.containsKey( name ) ) 226 { 227 i = super.getImplementationByName( name ); 228 this.implementationsByNameCache.put( name, i ); 229 } 230 231 return i; 232 } 233 } 234 235 /** 236 * Gets an implementation reference for a given identifier from the list of references. 237 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 238 * cached result object is available, this method queries the super-class for a result object to return and caches 239 * the outcome of that query for use on successive calls.</p> 240 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 241 * state of the instance, should the state of the instance change.</p> 242 * 243 * @param implementation The identifier of the reference to return. 244 * 245 * @return The first matching implementation reference or {@code null}, if no such reference is found. 246 * 247 * @throws NullPointerException if {@code implementation} is {@code null}. 248 * 249 * @see #getReference() 250 * @see ImplementationReference#getIdentifier() 251 * @see #clear() 252 */ 253 @Override 254 public ImplementationReference getReference( final String implementation ) 255 { 256 if ( implementation == null ) 257 { 258 throw new NullPointerException( "implementation" ); 259 } 260 261 synchronized ( this.referencesByIdentifierCache ) 262 { 263 ImplementationReference r = this.referencesByIdentifierCache.get( implementation ); 264 265 if ( r == null && !this.referencesByIdentifierCache.containsKey( implementation ) ) 266 { 267 r = super.getReference( implementation ); 268 this.referencesByIdentifierCache.put( implementation, r ); 269 } 270 271 return r; 272 } 273 } 274 275 private void copyImplementations() 276 { 277 for ( int i = 0, s0 = this.getImplementation().size(); i < s0; i++ ) 278 { 279 final Implementation impl = this.getImplementation().get( i ); 280 this.getImplementation().set( i, RuntimeModelObjects.getInstance().copyOf( impl ) ); 281 } 282 } 283 284 private void copyImplementationReferences() 285 { 286 for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ ) 287 { 288 final ImplementationReference r = this.getReference().get( i ); 289 this.getReference().set( i, RuntimeModelObjects.getInstance().copyOf( r ) ); 290 } 291 } 292 293 // SECTION-END 294 // SECTION-START[RuntimeModelObject] 295 public void gc() 296 { 297 this.gcOrClear( true, false ); 298 } 299 300 public void clear() 301 { 302 synchronized ( this.implementationsByClassCache ) 303 { 304 this.implementationsByClassCache.clear(); 305 } 306 synchronized ( this.implementationsByIdentifierCache ) 307 { 308 this.implementationsByIdentifierCache.clear(); 309 } 310 synchronized ( this.implementationsByNameCache ) 311 { 312 this.implementationsByNameCache.clear(); 313 } 314 synchronized ( this.referencesByIdentifierCache ) 315 { 316 this.referencesByIdentifierCache.clear(); 317 } 318 319 this.gcOrClear( false, true ); 320 } 321 322 private void gcOrClear( final boolean gc, final boolean clear ) 323 { 324 if ( this.getAuthors() instanceof RuntimeModelObject ) 325 { 326 if ( gc ) 327 { 328 ( (RuntimeModelObject) this.getAuthors() ).gc(); 329 } 330 if ( clear ) 331 { 332 ( (RuntimeModelObject) this.getAuthors() ).clear(); 333 } 334 } 335 if ( this.getDocumentation() instanceof RuntimeModelObject ) 336 { 337 if ( gc ) 338 { 339 ( (RuntimeModelObject) this.getDocumentation() ).gc(); 340 } 341 if ( clear ) 342 { 343 ( (RuntimeModelObject) this.getDocumentation() ).clear(); 344 } 345 } 346 347 this.gcOrClearImplementationReferences( gc, clear ); 348 this.gcOrClearImplementations( gc, clear ); 349 } 350 351 private void gcOrClearImplementations( final boolean gc, final boolean clear ) 352 { 353 for ( int i = 0, s0 = this.getImplementation().size(); i < s0; i++ ) 354 { 355 final Implementation impl = this.getImplementation().get( i ); 356 if ( impl instanceof RuntimeModelObject ) 357 { 358 if ( gc ) 359 { 360 ( (RuntimeModelObject) impl ).gc(); 361 } 362 if ( clear ) 363 { 364 ( (RuntimeModelObject) impl ).clear(); 365 } 366 } 367 } 368 } 369 370 private void gcOrClearImplementationReferences( final boolean gc, final boolean clear ) 371 { 372 for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ ) 373 { 374 final ImplementationReference r = this.getReference().get( i ); 375 if ( r instanceof RuntimeModelObject ) 376 { 377 if ( gc ) 378 { 379 ( (RuntimeModelObject) r ).gc(); 380 } 381 if ( clear ) 382 { 383 ( (RuntimeModelObject) r ).clear(); 384 } 385 } 386 } 387 } 388 389 // SECTION-END 390 // SECTION-START[Constructors] 391 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors "> 392 /** Creates a new {@code RuntimeImplementations} instance. */ 393 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" ) 394 public RuntimeImplementations() 395 { 396 // SECTION-START[Default Constructor] 397 super(); 398 // SECTION-END 399 } 400 // </editor-fold> 401 // SECTION-END 402 // SECTION-START[Dependencies] 403 // SECTION-END 404 // SECTION-START[Properties] 405 // SECTION-END 406 // SECTION-START[Messages] 407 // SECTION-END 408 }