/src/org/jruby/embed/osgi/internal/OSGiLoadService.java

https://github.com/saillinux/jruby · Java · 158 lines · 92 code · 11 blank · 55 comment · 19 complexity · 80383c2bc07f098586bd23a153a357c1 MD5 · raw file

  1. /***** BEGIN LICENSE BLOCK *****
  2. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Common Public
  5. * License Version 1.0 (the "License"); you may not use this file
  6. * except in compliance with the License. You may obtain a copy of
  7. * the License at http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Software distributed under the License is distributed on an "AS
  10. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11. * implied. See the License for the specific language governing
  12. * rights and limitations under the License.
  13. *
  14. * Copyright (C) 2002-2011 JRuby Community
  15. *
  16. * Alternatively, the contents of this file may be used under the terms of
  17. * either of the GNU General Public License Version 2 or later (the "GPL"),
  18. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  19. * in which case the provisions of the GPL or the LGPL are applicable instead
  20. * of those above. If you wish to allow use of your version of this file only
  21. * under the terms of either the GPL or the LGPL, and not to allow others to
  22. * use your version of this file under the terms of the CPL, indicate your
  23. * decision by deleting the provisions above and replace them with the notice
  24. * and other provisions required by the GPL or the LGPL. If you do not delete
  25. * the provisions above, a recipient may use your version of this file under
  26. * the terms of any one of the CPL, the GPL or the LGPL.
  27. ***** END LICENSE BLOCK *****/
  28. package org.jruby.embed.osgi.internal;
  29. import java.net.URL;
  30. import java.util.StringTokenizer;
  31. import org.jruby.Ruby;
  32. import org.jruby.RubyInstanceConfig.LoadServiceCreator;
  33. import org.jruby.embed.osgi.utils.OSGiFileLocator;
  34. import org.jruby.platform.Platform;
  35. import org.jruby.runtime.load.Library;
  36. import org.jruby.runtime.load.LoadService;
  37. import org.jruby.runtime.load.LoadServiceResource;
  38. import org.osgi.framework.Bundle;
  39. /**
  40. * @author hmalphettes
  41. *
  42. * Load scripts and java classes directly from the OSGi bundles.
  43. * bundle:/symbolic.name/
  44. */
  45. public class OSGiLoadService extends LoadService {
  46. public static final String OSGI_BUNDLE_CLASSPATH_SCHEME = "osgibundle:/";
  47. public static LoadServiceCreator OSGI_DEFAULT = new LoadServiceCreator() {
  48. public LoadService create(Ruby runtime) {
  49. if (runtime.is1_9()) {
  50. return new OSGiLoadService19(runtime);
  51. }
  52. return new OSGiLoadService(runtime);
  53. }
  54. };
  55. /**
  56. * Default constructor
  57. * Optional constructor (why?)
  58. * @param runtime
  59. */
  60. public OSGiLoadService(Ruby runtime) {
  61. super(runtime);
  62. // super.searchers.add(new OSGiBundlesSearcher());
  63. }
  64. /**
  65. * Support for 'bundle:/' to look for libraries in osgi bundles
  66. * or classes or ruby files.
  67. *
  68. * @mri rb_find_file
  69. * @param name the file to find, this is a path name
  70. * @return the correct file
  71. */
  72. @Override
  73. protected LoadServiceResource findFileInClasspath(String name) {
  74. if (name.startsWith(OSGI_BUNDLE_CLASSPATH_SCHEME)) {
  75. name = cleanupFindName(name);
  76. StringTokenizer tokenizer = new StringTokenizer(name, "/", false);
  77. tokenizer.nextToken();
  78. String symname = tokenizer.nextToken();
  79. StringBuilder sb = new StringBuilder();
  80. if (!tokenizer.hasMoreTokens()) {
  81. sb.append('/');
  82. } else {
  83. while (tokenizer.hasMoreTokens()) {
  84. sb.append('/');
  85. sb.append(tokenizer.nextToken());
  86. }
  87. }
  88. Bundle bundle = OSGiFileLocator.getBundle(symname);
  89. if (bundle != null) {
  90. URL url = bundle.getEntry(sb.toString());
  91. if (url != null) {
  92. return new LoadServiceResource(
  93. OSGiFileLocator.getLocalURL(url), name);
  94. }
  95. }
  96. }
  97. return super.findFileInClasspath(name);
  98. }
  99. /**
  100. * Support for 'bundle:/' to look for libraries in osgi bundles.
  101. */
  102. @Override
  103. protected Library createLibrary(SearchState state, LoadServiceResource resource) {
  104. if (resource == null) {
  105. return null;
  106. }
  107. String file = state.loadName;
  108. if (file.startsWith(OSGI_BUNDLE_CLASSPATH_SCHEME)) {
  109. file = cleanupFindName(file);
  110. StringTokenizer tokenizer = new StringTokenizer(file, "/", false);
  111. tokenizer.nextToken();
  112. String symname = tokenizer.nextToken();
  113. Bundle bundle = OSGiFileLocator.getBundle(symname);
  114. if (bundle != null) {
  115. return new OSGiBundleLibrary(bundle);
  116. }
  117. }
  118. return super.createLibrary(state, resource);
  119. }
  120. /**
  121. * Remove the extension when they are misleading.
  122. * @param name
  123. * @return
  124. */
  125. private String cleanupFindName(String name) {
  126. if (name.endsWith(".jar")) {
  127. return name.substring(0, name.length()-".jar".length());
  128. } else if (name.endsWith(".class")) {
  129. return name.substring(0, name.length()-".class".length());
  130. } else {
  131. return name;
  132. }
  133. }
  134. }
  135. class OSGiLoadService19 extends OSGiLoadService {
  136. public OSGiLoadService19(Ruby runtime) {
  137. super(runtime);
  138. }
  139. @Override
  140. protected String resolveLoadName(LoadServiceResource foundResource, String previousPath) {
  141. String path = foundResource.getAbsolutePath();
  142. if (Platform.IS_WINDOWS) {
  143. path = path.replace('\\', '/');
  144. }
  145. return path;
  146. }
  147. }