diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXDeployedBundle.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXDeployedBundle.java new file mode 100644 index 00000000000..006446940b3 --- /dev/null +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXDeployedBundle.java @@ -0,0 +1,148 @@ +package er.extensions.appserver; + + +import java.io.File; + +import com.webobjects._ideservices._WOProject; +import com.webobjects.appserver.WOApplication; +import com.webobjects.appserver._private.WODeployedBundle; +import com.webobjects.appserver._private.WOProjectBundle; +import com.webobjects.foundation.NSArray; +import com.webobjects.foundation.NSBundle; +import com.webobjects.foundation.NSLog; +import com.webobjects.foundation.NSMutableDictionary; +import com.webobjects.foundation.NSPathUtilities; +import com.webobjects.foundation.NSProperties; +import com.webobjects.foundation.NSPropertyListSerialization; +import com.webobjects.foundation._NSStringUtilities; + +public class ERXDeployedBundle extends WODeployedBundle { + + private final NSMutableDictionary _myURLs; + private static final NSMutableDictionary TheBundles = new NSMutableDictionary(NSBundle.frameworkBundles().count()); + private static final boolean _allowRapidTurnaround = NSPropertyListSerialization.booleanForString(NSProperties.getProperty("WOAllowRapidTurnaround")); + private boolean isEmbeddedFramework = false; + private String embeddingWrapperName = null; + + public ERXDeployedBundle(NSBundle nsb) + { + super(nsb); + + _myURLs = new NSMutableDictionary(); + + if(bundlePath().startsWith(NSBundle.mainBundle().bundlePath())) + { + isEmbeddedFramework = true; + embeddingWrapperName = NSBundle.mainBundle().name() + ".woa"; + } + } + + @Override + public String urlForResource(String resourceName, NSArray languagesList) { + + String aRelativePath = relativePathForResource(resourceName, languagesList); + String aURL = null; + synchronized(_myURLs) + { + aURL = _cachedURL(aRelativePath); + } + return aURL; + } + + private String _cachedURL(String aRelativePath) + { + String aURL = null; + if(aRelativePath != null) + { + aURL = (String)_myURLs.objectForKey(aRelativePath); + if(aURL == null) + { + String aBaseURL = null; + if(isFramework()) + if(isEmbeddedFramework) + aBaseURL = WOApplication.application().applicationBaseURL() + "/" + embeddingWrapperName + "/Frameworks"; + else + aBaseURL = WOApplication.application().frameworksBaseURL(); + else + aBaseURL = WOApplication.application().applicationBaseURL(); + String aWrapperName = wrapperName(); + if(aBaseURL != null && aWrapperName != null) + { + aURL = _NSStringUtilities.concat(aBaseURL, File.separator, aWrapperName, File.separator, aRelativePath); + aURL = NSPathUtilities._standardizedPath(aURL); + _myURLs.setObjectForKey(aURL, aRelativePath); + } + } + } + return aURL; + } + + public static synchronized WODeployedBundle bundleWithNSBundle(NSBundle nsBundle) + { + Object aBundle = TheBundles.objectForKey(nsBundle); + if(aBundle == null) + { + WODeployedBundle deployedBundle = new ERXDeployedBundle(nsBundle); + if(_allowRapidTurnaround) + { + String bundlePath = nsBundle.bundlePathURL().getPath(); + try + { + if(_WOProject.ideProjectAtPath(bundlePath) != null) + aBundle = new WOProjectBundle(bundlePath, deployedBundle); + else + aBundle = deployedBundle; + } + catch(Exception e) + { + if(NSLog.debugLoggingAllowedForLevel(1)) + { + NSLog.debug.appendln((new StringBuilder()).append(": Warning - Unable to find project at path ").append(nsBundle.bundlePathURL().getPath()).append(" - Ignoring project.").toString()); + NSLog.debug.appendln(e); + } + aBundle = deployedBundle; + } + } else + { + aBundle = deployedBundle; + } + TheBundles.setObjectForKey(aBundle, nsBundle); + } + return (WODeployedBundle)aBundle; + } + + public static synchronized WODeployedBundle deployedBundleForFrameworkNamed(String aFrameworkName) + { + WODeployedBundle aBundle = null; + NSArray bundleArray = TheBundles.allValues(); + int baCount = TheBundles.count(); + NSBundle nsBundle = NSBundle.bundleForName(aFrameworkName); + if(nsBundle == null) + nsBundle = NSBundle.bundleWithPath(aFrameworkName); + if(nsBundle != null) + { + int i = 0; + do + { + if(i >= baCount) + break; + WODeployedBundle aFrameworkBundle = (WODeployedBundle)bundleArray.objectAtIndex(i); + if(nsBundle.equals(aFrameworkBundle.nsBundle())) + { + aBundle = aFrameworkBundle; + WODeployedBundle dBundle = aBundle.projectBundle(); + if(dBundle != null) + aBundle = dBundle; + break; + } + i++; + } while(true); + } + return aBundle; + } + + public boolean isEmbedded() { + return isEmbeddedFramework; + } + +} diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXResourceManager.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXResourceManager.java index f5dcbff04e3..5278a019fbd 100644 --- a/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXResourceManager.java +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXResourceManager.java @@ -3,6 +3,7 @@ import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URL; +import java.util.Enumeration; import org.apache.commons.lang.CharEncoding; import org.apache.log4j.Logger; @@ -16,8 +17,11 @@ import com.webobjects.appserver._private.WOURLEncoder; import com.webobjects.appserver._private.WOURLValuedElementData; import com.webobjects.foundation.NSArray; +import com.webobjects.foundation.NSBundle; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSForwardException; +import com.webobjects.foundation.NSLog; +import com.webobjects.foundation.NSMutableDictionary; import com.webobjects.foundation.NSPathUtilities; import com.webobjects.foundation._NSStringUtilities; import com.webobjects.foundation._NSThreadsafeMutableDictionary; @@ -42,11 +46,13 @@ public class ERXResourceManager extends WOResourceManager { protected static Logger log = Logger.getLogger(ERXResourceManager.class); private WODeployedBundle TheAppProjectBundle; private _NSThreadsafeMutableDictionary _urlValuedElementsData; - private IVersionManager _versionManager; + private IVersionManager _versionManager; + private final _NSThreadsafeMutableDictionary _myFrameworkProjectBundles = new _NSThreadsafeMutableDictionary(new NSMutableDictionary(128)); private static final NSDictionary _mimeTypes = _additionalMimeTypes(); protected ERXResourceManager() { TheAppProjectBundle = _initAppBundle(); + _initFrameworkProjectBundles(); try { Field field = WOResourceManager.class.getDeclaredField("_urlValuedElementsData"); field.setAccessible(true); @@ -104,6 +110,15 @@ public IVersionManager versionManager() { return _versionManager; } + private void _initFrameworkProjectBundles() + { + NSBundle aBundle = null; + NSArray aFrameworkBundleList = NSBundle.frameworkBundles(); + for(Enumeration aBundleEnumerator = aFrameworkBundleList.objectEnumerator(); aBundleEnumerator.hasMoreElements(); _erxCachedBundleForFrameworkNamed(aBundle.name())) + aBundle = (NSBundle)aBundleEnumerator.nextElement(); + + } + private static WODeployedBundle _initAppBundle() { Object obj = null; try { @@ -123,10 +138,64 @@ private static WODeployedBundle _initAppBundle() { return (WODeployedBundle) obj; } - private String _cachedURLForResource(String name, String bundleName, NSArray languages, WORequest request) { + + private static WODeployedBundle _locateBundleForFrameworkNamed(String aFrameworkName) + { + WODeployedBundle aBundle = null; + aBundle = ERXDeployedBundle.deployedBundleForFrameworkNamed(aFrameworkName); + if(aBundle == null) + { + NSBundle nsBundle = NSBundle.bundleForName(aFrameworkName); + if(nsBundle != null) + aBundle = _bundleWithNSBundle(nsBundle); + } + return aBundle; + } + + private static WODeployedBundle _bundleWithNSBundle(NSBundle nsBundle) + { + WODeployedBundle aBundle = null; + WODeployedBundle aDeployedBundle = ERXDeployedBundle.bundleWithNSBundle(nsBundle); + WODeployedBundle aProjectBundle = aDeployedBundle.projectBundle(); + if(aProjectBundle != null) + { + if(WOApplication._isDebuggingEnabled()) + NSLog.debug.appendln((new StringBuilder()).append("Framework project found: Will locate resources in '").append(aProjectBundle.bundlePath()).append("' rather than '").append(aDeployedBundle.bundlePath()).append("' .").toString()); + aBundle = aProjectBundle; + } else + { + aBundle = aDeployedBundle; + } + return aBundle; + } + + public NSArray _frameworkProjectBundles() + { + return _myFrameworkProjectBundles.immutableClone().allValues(); + } + + public WODeployedBundle _erxCachedBundleForFrameworkNamed(String aFrameworkName) + { + WODeployedBundle aBundle = null; + if(aFrameworkName != null) + { + aBundle = (WODeployedBundle)_myFrameworkProjectBundles.objectForKey(aFrameworkName); + if(aBundle == null) + { + aBundle = _locateBundleForFrameworkNamed(aFrameworkName); + if(aBundle != null) + _myFrameworkProjectBundles.setObjectForKey(aBundle, aFrameworkName); + } + } + if(aBundle == null) + aBundle = TheAppProjectBundle; + return aBundle; + } + + private String _cachedURLForResource(String name, String bundleName, NSArray languages, WORequest request) { String result = null; if (bundleName != null) { - WODeployedBundle wodeployedbundle = _cachedBundleForFrameworkNamed(bundleName); + WODeployedBundle wodeployedbundle = _erxCachedBundleForFrameworkNamed(bundleName); if (wodeployedbundle != null) { result = wodeployedbundle.urlForResource(name, languages); }