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: RuntimeImplementation.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.lang.ref.Reference; 039 import java.lang.ref.WeakReference; 040 import java.net.URI; 041 import java.util.Map; 042 import org.jomc.model.Implementation; 043 import static org.jomc.ri.model.RuntimeModelObjects.BOOTSTRAP_CLASSLOADER_KEY; 044 import static org.jomc.ri.model.RuntimeModelObjects.classesByClassLoaderAndNameCache; 045 import static org.jomc.ri.model.RuntimeModelObjects.createMap; 046 047 // SECTION-START[Documentation] 048 // <editor-fold defaultstate="collapsed" desc=" Generated Documentation "> 049 /** 050 * Runtime {@code Implementation}. 051 * 052 * <dl> 053 * <dt><b>Identifier:</b></dt><dd>org.jomc.ri.model.RuntimeImplementation</dd> 054 * <dt><b>Name:</b></dt><dd>JOMC RI RuntimeImplementation</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:schulte2005@users.sourceforge.net">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.2.2", comments = "See http://jomc.sourceforge.net/jomc/1.2/jomc-tools-1.2.2" ) 070 // </editor-fold> 071 // SECTION-END 072 public class RuntimeImplementation extends Implementation implements RuntimeModelObject 073 { 074 // SECTION-START[RuntimeImplementation] 075 076 /** Cached location URI. */ 077 private volatile URI locationUri; 078 079 /** 080 * Creates a new {@code RuntimeImplementation} instance by deeply copying a given {@code Implementation} instance. 081 * 082 * @param implementation The instance to copy. 083 * 084 * @throws NullPointerException if {@code implementation} is {@code null}. 085 */ 086 public RuntimeImplementation( final Implementation implementation ) 087 { 088 super( implementation ); 089 090 if ( this.getAuthors() != null ) 091 { 092 this.setAuthors( RuntimeModelObjects.getInstance().copyOf( this.getAuthors() ) ); 093 } 094 if ( this.getDependencies() != null ) 095 { 096 this.setDependencies( RuntimeModelObjects.getInstance().copyOf( this.getDependencies() ) ); 097 } 098 if ( this.getDocumentation() != null ) 099 { 100 this.setDocumentation( RuntimeModelObjects.getInstance().copyOf( this.getDocumentation() ) ); 101 } 102 if ( this.getImplementations() != null ) 103 { 104 this.setImplementations( RuntimeModelObjects.getInstance().copyOf( this.getImplementations() ) ); 105 } 106 if ( this.getMessages() != null ) 107 { 108 this.setMessages( RuntimeModelObjects.getInstance().copyOf( this.getMessages() ) ); 109 } 110 if ( this.getProperties() != null ) 111 { 112 this.setProperties( RuntimeModelObjects.getInstance().copyOf( this.getProperties() ) ); 113 } 114 if ( this.getSpecifications() != null ) 115 { 116 this.setSpecifications( RuntimeModelObjects.getInstance().copyOf( this.getSpecifications() ) ); 117 } 118 } 119 120 /** 121 * Gets the location URI used for locating instances of this implementation. 122 * <p>This method queries an internal cache for a result object to return. If no cached result object is available, 123 * this method queries the super-class for a result object to return and caches the outcome of that query for use on 124 * successive calls.</p> 125 * <p><b>Note:</b><br/>Method {@code clear()} must be used to synchronize the state of the internal cache with the 126 * state of the instance, should the state of the instance change.</p> 127 * 128 * @return The location URI used for locating instances of this implementation or {@code null}, if instances of this 129 * implementation do not need to be located. 130 * 131 * @see #getLocation() 132 * @see #clear() 133 */ 134 @Override 135 public URI getLocationUri() 136 { 137 if ( this.locationUri == null ) 138 { 139 this.locationUri = super.getLocationUri(); 140 } 141 142 return this.locationUri; 143 } 144 145 /** 146 * Gets the Java class of the implementation for a given class loader. 147 * <p>This method queries an internal cache for a result object to return for the given argument values. If no 148 * cached result object is available, this method queries the super-class for a result object to return and caches 149 * the outcome of that query for use on successive calls.</p> 150 * <p><b>Note:</b><br/>Method {@code RuntimeModelObjects.clear()} must be used to synchronize the state of the 151 * internal cache with the state of the class loader, should the state of the class loader change.</p> 152 * 153 * @param classLoader The class loader to get the Java class from or {@code null}, to get the Java class from the 154 * platform's bootstrap class loader. 155 * 156 * @return The Java class of the implementation or {@code null}, if the implementation does not declare a class. 157 * 158 * @throws ClassNotFoundException if the Java class is not found. 159 * 160 * @see #getClazz() 161 * @see RuntimeModelObjects#clear() 162 */ 163 @Override 164 public Class<?> getJavaClass( final ClassLoader classLoader ) throws ClassNotFoundException 165 { 166 Class<?> javaClass = null; 167 168 if ( this.getClazz() != null ) 169 { 170 ClassLoader classLoaderKey = classLoader; 171 if ( classLoaderKey == null ) 172 { 173 classLoaderKey = BOOTSTRAP_CLASSLOADER_KEY; 174 } 175 176 synchronized ( classesByClassLoaderAndNameCache ) 177 { 178 Map<String, Reference<Class<?>>> map = classesByClassLoaderAndNameCache.get( classLoaderKey ); 179 180 if ( map == null ) 181 { 182 map = createMap(); 183 classesByClassLoaderAndNameCache.put( classLoaderKey, map ); 184 } 185 186 final Reference<Class<?>> reference = map.get( this.getClazz() ); 187 188 if ( reference != null ) 189 { 190 javaClass = reference.get(); 191 } 192 193 if ( javaClass == null ) 194 { 195 javaClass = super.getJavaClass( classLoader ); 196 map.put( this.getClazz(), new WeakReference<Class<?>>( javaClass ) ); 197 } 198 } 199 } 200 201 return javaClass; 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 this.locationUri = null; 214 this.gcOrClear( false, true ); 215 } 216 217 private void gcOrClear( final boolean gc, final boolean clear ) 218 { 219 if ( this.getAuthors() instanceof RuntimeModelObject ) 220 { 221 if ( gc ) 222 { 223 ( (RuntimeModelObject) this.getAuthors() ).gc(); 224 } 225 if ( clear ) 226 { 227 ( (RuntimeModelObject) this.getAuthors() ).clear(); 228 } 229 } 230 if ( this.getDependencies() instanceof RuntimeModelObject ) 231 { 232 if ( gc ) 233 { 234 ( (RuntimeModelObject) this.getDependencies() ).gc(); 235 } 236 if ( clear ) 237 { 238 ( (RuntimeModelObject) this.getDependencies() ).clear(); 239 } 240 } 241 if ( this.getDocumentation() instanceof RuntimeModelObject ) 242 { 243 if ( gc ) 244 { 245 ( (RuntimeModelObject) this.getDocumentation() ).gc(); 246 } 247 if ( clear ) 248 { 249 ( (RuntimeModelObject) this.getDocumentation() ).clear(); 250 } 251 } 252 if ( this.getImplementations() instanceof RuntimeModelObject ) 253 { 254 if ( gc ) 255 { 256 ( (RuntimeModelObject) this.getImplementations() ).gc(); 257 } 258 if ( clear ) 259 { 260 ( (RuntimeModelObject) this.getImplementations() ).clear(); 261 } 262 } 263 if ( this.getMessages() instanceof RuntimeModelObject ) 264 { 265 if ( gc ) 266 { 267 ( (RuntimeModelObject) this.getMessages() ).gc(); 268 } 269 if ( clear ) 270 { 271 ( (RuntimeModelObject) this.getMessages() ).clear(); 272 } 273 } 274 if ( this.getProperties() instanceof RuntimeModelObject ) 275 { 276 if ( gc ) 277 { 278 ( (RuntimeModelObject) this.getProperties() ).gc(); 279 } 280 if ( clear ) 281 { 282 ( (RuntimeModelObject) this.getProperties() ).clear(); 283 } 284 } 285 if ( this.getSpecifications() instanceof RuntimeModelObject ) 286 { 287 if ( gc ) 288 { 289 ( (RuntimeModelObject) this.getSpecifications() ).gc(); 290 } 291 if ( clear ) 292 { 293 ( (RuntimeModelObject) this.getSpecifications() ).clear(); 294 } 295 } 296 } 297 298 // SECTION-END 299 // SECTION-START[Constructors] 300 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors "> 301 /** Creates a new {@code RuntimeImplementation} instance. */ 302 @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" ) 303 public RuntimeImplementation() 304 { 305 // SECTION-START[Default Constructor] 306 super(); 307 // SECTION-END 308 } 309 // </editor-fold> 310 // SECTION-END 311 // SECTION-START[Dependencies] 312 // SECTION-END 313 // SECTION-START[Properties] 314 // SECTION-END 315 // SECTION-START[Messages] 316 // SECTION-END 317 }