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: RuntimeProperties.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.Properties; 041 import org.jomc.model.Property; 042 import org.jomc.model.PropertyReference; 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 Properties}. 049 * 050 * <dl> 051 * <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeProperties</dd> 052 * <dt><b>Name:</b></dt><dd>JOMC RI RuntimeProperties</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 RuntimeProperties extends Properties implements RuntimeModelObject 071 { 072 // SECTION-START[RuntimeProperties] 073 074 /** Cache map. */ 075 @XmlTransient 076 private transient final Map<String, Property> propertiesByNameCache = createMap(); 077 078 /** Cache map. */ 079 @XmlTransient 080 private transient final Map<String, PropertyReference> referencesByNameCache = createMap(); 081 082 /** 083 * Creates a new {@code RuntimeProperties} instance by deeply copying a given {@code Properties} instance. 084 * 085 * @param properties The instance to copy. 086 * 087 * @throws NullPointerException if {@code properties} is {@code null}. 088 */ 089 public RuntimeProperties( final Properties properties ) 090 { 091 super( properties ); 092 093 if ( this.getAuthors() != null ) 094 { 095 this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) ); 096 } 097 if ( this.getDocumentation() != null ) 098 { 099 this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) ); 100 } 101 102 this.copyProperties(); 103 this.copyReferences(); 104 } 105 106 /** 107 * Gets a property for a given name from the list of properties. 108 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 109 * cached result object is available, this method queries the super-class for a result object to return and caches 110 * the outcome of that query for use on successive calls.</p> 111 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 112 * state of the instance, should the state of the instance change.</p> 113 * 114 * @param name The name of the property to return. 115 * 116 * @return The first matching property or {@code null}, if no such property is found. 117 * 118 * @throws NullPointerException if {@code name} is {@code null}. 119 * 120 * @see #getProperty() 121 * @see Property#getName() 122 * @see #clear() 123 */ 124 @Override 125 public Property getProperty( final String name ) 126 { 127 if ( name == null ) 128 { 129 throw new NullPointerException( "name" ); 130 } 131 132 synchronized ( this.propertiesByNameCache ) 133 { 134 Property p = this.propertiesByNameCache.get( name ); 135 136 if ( p == null && !this.propertiesByNameCache.containsKey( name ) ) 137 { 138 p = super.getProperty( name ); 139 this.propertiesByNameCache.put( name, p ); 140 } 141 142 return p; 143 } 144 } 145 146 /** 147 * Gets a property reference for a given name from the list of references. 148 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 149 * cached result object is available, this method queries the super-class for a result object to return and caches 150 * the outcome of that query for use on successive calls.</p> 151 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 152 * state of the instance, should the state of the instance change.</p> 153 * 154 * @param name The name of the property reference to return. 155 * 156 * @return The first matching property reference or {@code null}, if no such reference is found. 157 * 158 * @throws NullPointerException if {@code name} is {@code null}. 159 * 160 * @see #getReference() 161 * @see PropertyReference#getName() 162 * @see #clear() 163 */ 164 @Override 165 public PropertyReference getReference( final String name ) 166 { 167 if ( name == null ) 168 { 169 throw new NullPointerException( "name" ); 170 } 171 172 synchronized ( this.referencesByNameCache ) 173 { 174 PropertyReference r = this.referencesByNameCache.get( name ); 175 176 if ( r == null && !this.referencesByNameCache.containsKey( name ) ) 177 { 178 r = super.getReference( name ); 179 this.referencesByNameCache.put( name, r ); 180 } 181 182 return r; 183 } 184 } 185 186 private void copyProperties() 187 { 188 for ( int i = 0, s0 = this.getProperty().size(); i < s0; i++ ) 189 { 190 final Property p = this.getProperty().get( i ); 191 this.getProperty().set( i, RuntimeModelObjects.getInstance().copyOf( p ) ); 192 } 193 } 194 195 private void copyReferences() 196 { 197 for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ ) 198 { 199 final PropertyReference r = this.getReference().get( i ); 200 this.getReference().set( i, RuntimeModelObjects.getInstance().copyOf( r ) ); 201 } 202 } 203 204 // SECTION-END 205 // SECTION-START[RuntimeModelObject] 206 public void gc() 207 { 208 this.gcOrClear( true, false ); 209 } 210 211 public void clear() 212 { 213 synchronized ( this.propertiesByNameCache ) 214 { 215 this.propertiesByNameCache.clear(); 216 } 217 synchronized ( this.referencesByNameCache ) 218 { 219 this.referencesByNameCache.clear(); 220 } 221 222 this.gcOrClear( false, true ); 223 } 224 225 private void gcOrClear( final boolean gc, final boolean clear ) 226 { 227 if ( this.getAuthors() instanceof RuntimeModelObject ) 228 { 229 if ( gc ) 230 { 231 ( (RuntimeModelObject) this.getAuthors() ).gc(); 232 } 233 if ( clear ) 234 { 235 ( (RuntimeModelObject) this.getAuthors() ).clear(); 236 } 237 } 238 if ( this.getDocumentation() instanceof RuntimeModelObject ) 239 { 240 if ( gc ) 241 { 242 ( (RuntimeModelObject) this.getDocumentation() ).gc(); 243 } 244 if ( clear ) 245 { 246 ( (RuntimeModelObject) this.getDocumentation() ).clear(); 247 } 248 } 249 250 this.gcOrClearProperties( gc, clear ); 251 this.gcOrClearReferences( gc, clear ); 252 } 253 254 private void gcOrClearProperties( final boolean gc, final boolean clear ) 255 { 256 for ( int i = 0, s0 = this.getProperty().size(); i < s0; i++ ) 257 { 258 final Property p = this.getProperty().get( i ); 259 if ( p instanceof RuntimeModelObject ) 260 { 261 if ( gc ) 262 { 263 ( (RuntimeModelObject) p ).gc(); 264 } 265 if ( clear ) 266 { 267 ( (RuntimeModelObject) p ).clear(); 268 } 269 } 270 } 271 } 272 273 private void gcOrClearReferences( final boolean gc, final boolean clear ) 274 { 275 for ( int i = 0, s0 = this.getReference().size(); i < s0; i++ ) 276 { 277 final PropertyReference r = this.getReference().get( i ); 278 if ( r instanceof RuntimeModelObject ) 279 { 280 if ( gc ) 281 { 282 ( (RuntimeModelObject) r ).gc(); 283 } 284 if ( clear ) 285 { 286 ( (RuntimeModelObject) r ).clear(); 287 } 288 } 289 } 290 } 291 292 // SECTION-END 293 // SECTION-START[Constructors] 294 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors "> 295 /** Creates a new {@code RuntimeProperties} instance. */ 296 @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" ) 297 public RuntimeProperties() 298 { 299 // SECTION-START[Default Constructor] 300 super(); 301 // SECTION-END 302 } 303 // </editor-fold> 304 // SECTION-END 305 // SECTION-START[Dependencies] 306 // SECTION-END 307 // SECTION-START[Properties] 308 // SECTION-END 309 // SECTION-START[Messages] 310 // SECTION-END 311 }