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: RuntimeSpecifications.java 4588 2012-06-03 06:01:30Z schulte2005 $ 032 * 033 */ 034// </editor-fold> 035// SECTION-END 036package org.jomc.ri.model; 037 038import java.util.Map; 039import javax.xml.bind.annotation.XmlTransient; 040import org.jomc.model.Specification; 041import org.jomc.model.SpecificationReference; 042import org.jomc.model.Specifications; 043import static org.jomc.ri.model.RuntimeModelObjects.createMap; 044 045// SECTION-START[Documentation] 046// <editor-fold defaultstate="collapsed" desc=" Generated Documentation "> 047/** 048 * Runtime {@code Specifications}. 049 * 050 * <dl> 051 * <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeSpecifications</dd> 052 * <dt><b>Name:</b></dt><dd>JOMC RI RuntimeSpecifications</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.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" ) 068// </editor-fold> 069// SECTION-END 070public class RuntimeSpecifications extends Specifications implements RuntimeModelObject 071{ 072 // SECTION-START[RuntimeSpecifications] 073 074 /** Cache map. */ 075 @XmlTransient 076 private transient final Map<String, Specification> specificationsByIdentifierCache = createMap(); 077 078 /** Cache map. */ 079 @XmlTransient 080 private transient final Map<String, Specification> specificationsByClassCache = createMap(); 081 082 /** Cache map. */ 083 @XmlTransient 084 private transient final Map<String, SpecificationReference> referencesByIdentifierCache = createMap(); 085 086 /** 087 * Creates a new {@code RuntimeSpecifications} instance by deeply copying a given {@code Specifications} instance. 088 * 089 * @param specifications The instance to copy. 090 * 091 * @throws NullPointerException if {@code specifications} is {@code null}. 092 */ 093 public RuntimeSpecifications( final Specifications specifications ) 094 { 095 super( specifications ); 096 097 if ( this.getAuthors() != null ) 098 { 099 this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) ); 100 } 101 if ( this.getDocumentation() != null ) 102 { 103 this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) ); 104 } 105 106 this.copySpecifications(); 107 this.copyReferences(); 108 } 109 110 /** 111 * Gets a specification for a given identifier from the list of specifications. 112 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 113 * cached result object is available, this method queries the super-class for a result object to return and caches 114 * the outcome of that query for use on successive calls.</p> 115 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 116 * state of the instance, should the state of the instance change.</p> 117 * 118 * @param specification The identifier of the specification to return. 119 * 120 * @return The first matching specification or {@code null}, if no such specification is found. 121 * 122 * @throws NullPointerException if {@code specification} is {@code null}. 123 * 124 * @see #getSpecification() 125 * @see Specification#getIdentifier() 126 * @see #clear() 127 */ 128 @Override 129 public Specification getSpecification( final String specification ) 130 { 131 if ( specification == null ) 132 { 133 throw new NullPointerException( "specification" ); 134 } 135 136 synchronized ( this.specificationsByIdentifierCache ) 137 { 138 Specification s = this.specificationsByIdentifierCache.get( specification ); 139 140 if ( s == null && !this.specificationsByIdentifierCache.containsKey( specification ) ) 141 { 142 s = super.getSpecification( specification ); 143 this.specificationsByIdentifierCache.put( specification, s ); 144 } 145 146 return s; 147 } 148 } 149 150 /** 151 * Gets a specification for a given class from the list of specifications. 152 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 153 * cached result object is available, this method queries the super-class for a result object to return and caches 154 * the outcome of that query for use on successive calls.</p> 155 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 156 * state of the instance, should the state of the instance change.</p> 157 * 158 * @param specification The class of the specification to return. 159 * 160 * @return The first matching specification or {@code null}, if no such specification is found. 161 * 162 * @throws NullPointerException if {@code specification} is {@code null}. 163 * 164 * @see #getSpecification() 165 * @see Specification#isClassDeclaration() 166 * @see Specification#getClazz() 167 * @see #clear() 168 */ 169 @Override 170 public Specification getSpecification( final Class<?> specification ) 171 { 172 if ( specification == null ) 173 { 174 throw new NullPointerException( "specification" ); 175 } 176 177 synchronized ( this.specificationsByClassCache ) 178 { 179 Specification s = this.specificationsByClassCache.get( specification.getName() ); 180 181 if ( s == null && !this.specificationsByClassCache.containsKey( specification.getName() ) ) 182 { 183 s = super.getSpecification( specification ); 184 this.specificationsByClassCache.put( specification.getName(), s ); 185 } 186 187 return s; 188 } 189 } 190 191 /** 192 * Gets a specification reference for a given identifier from the list of references. 193 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 194 * cached result object is available, this method queries the super-class for a result object to return and caches 195 * the outcome of that query for use on successive calls.</p> 196 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 197 * state of the instance, should the state of the instance change.</p> 198 * 199 * @param specification The identifier of the reference to return. 200 * 201 * @return The first matching specification reference or {@code null}, if no such specification reference is found. 202 * 203 * @throws NullPointerException if {@code specification} is {@code null}. 204 * 205 * @see #getReference() 206 * @see SpecificationReference#getIdentifier() 207 * @see #clear() 208 */ 209 @Override 210 public SpecificationReference getReference( final String specification ) 211 { 212 if ( specification == null ) 213 { 214 throw new NullPointerException( "specification" ); 215 } 216 217 synchronized ( this.referencesByIdentifierCache ) 218 { 219 SpecificationReference r = this.referencesByIdentifierCache.get( specification ); 220 221 if ( r == null && !this.referencesByIdentifierCache.containsKey( specification ) ) 222 { 223 r = super.getReference( specification ); 224 this.referencesByIdentifierCache.put( specification, r ); 225 } 226 227 return r; 228 } 229 } 230 231 private void copySpecifications() 232 { 233 for ( int i = 0, s0 = this.getSpecification().size(); i < s0; i++ ) 234 { 235 final Specification s = this.getSpecification().get( i ); 236 this.getSpecification().set( i, RuntimeModelObjects.getInstance().copyOf( s ) ); 237 } 238 } 239 240 private void copyReferences() 241 { 242 for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ ) 243 { 244 final SpecificationReference r = this.getReference().get( i ); 245 this.getReference().set( i, RuntimeModelObjects.getInstance().copyOf( r ) ); 246 } 247 } 248 249 // SECTION-END 250 // SECTION-START[RuntimeModelObject] 251 public void gc() 252 { 253 this.gcOrClear( true, false ); 254 } 255 256 public void clear() 257 { 258 synchronized ( this.specificationsByClassCache ) 259 { 260 this.specificationsByClassCache.clear(); 261 } 262 synchronized ( this.specificationsByIdentifierCache ) 263 { 264 this.specificationsByIdentifierCache.clear(); 265 } 266 synchronized ( this.referencesByIdentifierCache ) 267 { 268 this.referencesByIdentifierCache.clear(); 269 } 270 271 this.gcOrClear( false, true ); 272 } 273 274 private void gcOrClear( final boolean gc, final boolean clear ) 275 { 276 if ( this.getAuthors() instanceof RuntimeModelObject ) 277 { 278 if ( gc ) 279 { 280 ( (RuntimeModelObject) this.getAuthors() ).gc(); 281 } 282 if ( clear ) 283 { 284 ( (RuntimeModelObject) this.getAuthors() ).clear(); 285 } 286 } 287 if ( this.getDocumentation() instanceof RuntimeModelObject ) 288 { 289 if ( gc ) 290 { 291 ( (RuntimeModelObject) this.getDocumentation() ).gc(); 292 } 293 if ( clear ) 294 { 295 ( (RuntimeModelObject) this.getDocumentation() ).clear(); 296 } 297 } 298 299 this.gcOrClearReferences( gc, clear ); 300 this.gcOrClearSpecifications( gc, clear ); 301 } 302 303 private void gcOrClearSpecifications( final boolean gc, final boolean clear ) 304 { 305 for ( int i = 0, s0 = this.getSpecification().size(); i < s0; i++ ) 306 { 307 final Specification s = this.getSpecification().get( i ); 308 if ( s instanceof RuntimeModelObject ) 309 { 310 if ( gc ) 311 { 312 ( (RuntimeModelObject) s ).gc(); 313 } 314 if ( clear ) 315 { 316 ( (RuntimeModelObject) s ).clear(); 317 } 318 } 319 } 320 } 321 322 private void gcOrClearReferences( final boolean gc, final boolean clear ) 323 { 324 for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ ) 325 { 326 final SpecificationReference r = this.getReference().get( i ); 327 if ( r instanceof RuntimeModelObject ) 328 { 329 if ( gc ) 330 { 331 ( (RuntimeModelObject) r ).gc(); 332 } 333 if ( clear ) 334 { 335 ( (RuntimeModelObject) r ).clear(); 336 } 337 } 338 } 339 } 340 // SECTION-END 341 // SECTION-START[Constructors] 342 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors "> 343 /** Creates a new {@code RuntimeSpecifications} instance. */ 344 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.3", comments = "See http://jomc.sourceforge.net/jomc/1.3/jomc-tools-1.3" ) 345 public RuntimeSpecifications() 346 { 347 // SECTION-START[Default Constructor] 348 super(); 349 // SECTION-END 350 } 351 // </editor-fold> 352 // SECTION-END 353 // SECTION-START[Dependencies] 354 // SECTION-END 355 // SECTION-START[Properties] 356 // SECTION-END 357 // SECTION-START[Messages] 358 // SECTION-END 359}