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