001/* This is the preferred <code>ClassLoadingStrategy</code> implementation in a full-blown OSGi-based runtime. 002 003Copyright (c) 2015-2016 The Regents of the University of California; iSencia Belgium NV. 004All rights reserved. 005 006Permission is hereby granted, without written agreement and without 007license or royalty fees, to use, copy, modify, and distribute this 008software and its documentation for any purpose, provided that the above 009copyright notice and the following two paragraphs appear in all copies 010of this software. 011 012IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA LIABLE TO ANY PARTY 013FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016SUCH DAMAGE. 017 018THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023ENHANCEMENTS, OR MODIFICATIONS. 024 025PT_COPYRIGHT_VERSION_2 026COPYRIGHTENDKEY 027*/ 028 029package org.ptolemy.classloading.osgi; 030 031import java.util.HashSet; 032import java.util.Set; 033 034import org.ptolemy.classloading.ActorOrientedClassProvider; 035import org.ptolemy.classloading.ClassLoadingStrategy; 036import org.ptolemy.classloading.ModelElementClassProvider; 037import org.ptolemy.commons.VersionSpecification; 038 039import ptolemy.kernel.CompositeEntity; 040 041/** 042 * This is the preferred <code>ClassLoadingStrategy</code> implementation in a full-blown OSGi-based runtime. 043 * It supports dynamic actor class updates through OSGi's great dynamism based on micro-services. 044 * <p> 045 * This dynamism is obtained by delegating the class loading to the registered implementations of 046 * <code>ModelElementClassProvider</code> and <code>ActorOrientedClassProvider</code>. 047 * </p> 048 * 049 * @author ErwinDL 050 * @version $Id$ 051 * @since Ptolemy II 11.0 052 * @Pt.ProposedRating Yellow (ErwinDL) 053 * @Pt.AcceptedRating Yellow (ErwinDL) 054 */ 055public class OSGiClassLoadingStrategy implements ClassLoadingStrategy { 056 057 /////////////////////////////////////////////////////////////////// 058 //// public methods //// 059 060 /** 061 * Load a Java class. 062 * @param className The namee of the class. 063 * @param versionSpec The version 064 * @return the Class for the given name. 065 * @exception ClassNotFoundException If the class is not found. 066 */ 067 @Override 068 public Class<?> loadJavaClass(String className, 069 VersionSpecification versionSpec) throws ClassNotFoundException { 070 Class<?> result = null; 071 072 for (ModelElementClassProvider classProvider : _modelElementClassProviders) { 073 try { 074 result = classProvider.getClass(className, versionSpec); 075 if (result != null) { 076 break; 077 } 078 } catch (ClassNotFoundException e) { 079 // just means the provider doesn't know about this one 080 } 081 } 082 if (result != null) { 083 return result; 084 } else { 085 throw new ClassNotFoundException(className); 086 } 087 } 088 089 /** 090 * Load an actor-oriented class, which is typically a .moml file. 091 * @param className The namee of the class. 092 * @param versionSpec The version 093 * @return the Class for the given name. 094 * @exception ClassNotFoundException If the class is not found. 095 */ 096 @Override 097 public CompositeEntity loadActorOrientedClass(String className, 098 VersionSpecification versionSpec) throws ClassNotFoundException { 099 CompositeEntity result = null; 100 101 for (ActorOrientedClassProvider classProvider : _actorOrientedClassProviders) { 102 try { 103 result = classProvider.getActorOrientedClass(className, 104 versionSpec); 105 if (result != null) { 106 break; 107 } 108 } catch (ClassNotFoundException e) { 109 // just means the provider doesn't know about this one 110 } 111 } 112 if (result != null) { 113 return result; 114 } else { 115 throw new ClassNotFoundException(className); 116 } 117 } 118 119 // provider registration mgmt stuff 120 121 /** 122 * Add the given provider to the set of registered 123 * ModelElementClassProviders. 124 * 125 * @param classProvider should be not-null 126 * @return true if the entry was added successfully 127 * @exception IllegalArgumentException when the given provider is null 128 */ 129 public boolean addModelElementClassProvider( 130 ModelElementClassProvider classProvider) { 131 if (classProvider == null) { 132 throw new IllegalArgumentException("classProvider can not be null"); 133 } 134 return _modelElementClassProviders.add(classProvider); 135 } 136 137 /** 138 * Remove the given provider from the set of registered 139 * ModelElementClassProviders. 140 * 141 * @param classProvider should be not-null 142 * @return true if the set of registered providers contained the 143 * given instance and it was removed successfully 144 * @exception IllegalArgumentException when the given provider is null 145 */ 146 public boolean removeModelElementClassProvider( 147 ModelElementClassProvider classProvider) { 148 if (classProvider == null) { 149 throw new IllegalArgumentException("classProvider can not be null"); 150 } 151 return _modelElementClassProviders.remove(classProvider); 152 } 153 154 /** 155 * Clears the set of registered ModelElementClassProviders. 156 * Does not touch the registered ActorOrientedClassProviders. 157 */ 158 public void clearModelElementClassProviders() { 159 _modelElementClassProviders.clear(); 160 } 161 162 /** 163 * Adds the given provider to the set of registered ActorOrientedClassProviders. 164 * 165 * @param classProvider should be not-null 166 * @return true if the entry was added successfully 167 * @exception IllegalArgumentException when the given provider is null 168 */ 169 public boolean addActorOrientedClassProvider( 170 ActorOrientedClassProvider classProvider) { 171 if (classProvider == null) { 172 throw new IllegalArgumentException("classProvider can not be null"); 173 } 174 return _actorOrientedClassProviders.add(classProvider); 175 } 176 177 /** 178 * Removes the given provider from the set of registered ActorOrientedClassProviders. 179 * 180 * @param classProvider should be not-null 181 * @return true if the set of registered providers contained the 182 * given instance and it was removed successfully 183 * @exception IllegalArgumentException when the given provider is null 184 */ 185 public boolean removeActorOrientedClassProvider( 186 ActorOrientedClassProvider classProvider) { 187 return _actorOrientedClassProviders.remove(classProvider); 188 } 189 190 /** 191 * Clear the set of registered ActorOrientedClassProviders. 192 * Does not touch the registered ModelElementClassProviders. 193 */ 194 public void clearActorOrientedClassProviders() { 195 _actorOrientedClassProviders.clear(); 196 } 197 198 /////////////////////////////////////////////////////////////////// 199 //// private methods //// 200 201 /** All registered providers for "plain" model elements like actors, directors, ...*/ 202 private Set<ModelElementClassProvider> _modelElementClassProviders = new HashSet<ModelElementClassProvider>(); 203 /** All registered providers for actor-oriented classes in a model */ 204 private Set<ActorOrientedClassProvider> _actorOrientedClassProviders = new HashSet<ActorOrientedClassProvider>(); 205}