summaryrefslogtreecommitdiff
path: root/java/src/ServiceRepository.java
blob: 9ae7ed12668c9edf61f521e3902188efe5f35228 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*************************************************
 *
 * = PACKAGE
 *    ACE.ServiceConfigurator
 *
 * = FILENAME
 *    ServiceRepository.java
 *
 *@author Prashant Jain
 *
 *************************************************/
package ACE.ServiceConfigurator;

import java.io.*;
import java.util.*;
import ACE.OS.*;

public class ServiceRepository
{
  /**
   * Create a Service Repository.
   */
  public ServiceRepository ()
  {
    this.loader_ = new ServiceLoader ();
  }

  /**
   * Load a Java Class. This method first checks if the class is
   * already in the repository. If it is not, it checks if the class
   * is a system class and can be found on the local system. If both
   * these fail, the method tries to load the bytes for the class and
   * then create the Class from these bytes.
   *@param name name of the class to find in the repository
   *@return Class corresponding to name
   */
  public Class load (String name) throws ClassNotFoundException
  {
    return this.loader_.loadClass (name, true);
  }

  private ServiceLoader loader_;
}

class ServiceLoader extends ClassLoader
{
  public ServiceLoader ()
  {
    super ();
    this.getClassPath ();
  }
  
  // Load a compiled class file into runtime
  public Class loadClass (String name, boolean resolve) throws ClassNotFoundException
  {
    Class newClass;
    try
      {
	// Try to load it the class by reading in the bytes.
	// Note that we are not catching ClassNotFoundException here
	// since our caller will catch it.
	try
	  {
	    byte[] buf = bytesForClass (name);
	    newClass = defineClass (buf, 0, buf.length);
	    //	    ACE.DEBUG ("Loaded class: "+ name);
	    
	    // Check if we need to load other classes referred to by this class.
	    if (resolve)
	      resolveClass (newClass);
	  }
	catch (ClassNotFoundException e)
	  {
	    //	    ACE.DEBUG ("Using default loader for class: "+ name);
	    // Try default system loader
	    if ((newClass = findSystemClass (name)) != null)
	      return newClass;
	    else 
	      throw (e);   // Rethrow the exception
	  }
      }
    catch (IOException e)
      {
	throw new ClassNotFoundException (e.toString ());
      }
    return newClass;
  }

  private void getClassPath ()
  {
    // Cache system properties that are needed when trying to find a
    // class file
    this.classPath_     = System.getProperty ("java.class.path", ".");
    this.pathSeparator_ = System.getProperty ("path.separator", ":");
    this.fileSeparator_ = System.getProperty ("file.separator", "/");
  }

  // Read a file into a byte array
  private byte[] bytesForClass (String name) throws IOException, ClassNotFoundException
  {
    // Break up the CLASSPATH to check for existence of file in each
    // sub-path. Note that we use the path_separator to extract every
    // sub-path and use that to check if the class file exists.
    StringTokenizer tokens = new StringTokenizer (this.classPath_, 
						  this.pathSeparator_);
    while (tokens.hasMoreTokens ())
      {
	// Create a File object which can then be used to see if the
	// class file actually exists
	File classFile = new File (tokens.nextToken () + 
				    this.fileSeparator_ + 
				    name + 
				    ".class");

	// Check if file exists, is a normal file and is readable
	if (classFile.exists () && 
	    classFile.isFile () &&
	    classFile.canRead ())
	  {    
	    // Set up the stream
	    FileInputStream in = new FileInputStream (classFile);

	    // Get byte count
	    int length = in.available ();
	    
	    if (length == 0)
	      throw new ClassNotFoundException (name);

	    // Create an array of bytes to read the file in
	    byte[] buf = new byte[length];

	    // Read the file
	    in.read (buf);

	    // Return byte array
	    return buf;
	  }
      }
    // File was not found so throw an exception.
    throw new ClassNotFoundException ("Class file " + name + " not found");
  }

  private String classPath_;
  // Class path that is loaded at construction

  private String pathSeparator_;
  // Platform-dependent path separator (e.g., : or ;)

  private String fileSeparator_;
  // Platform-dependent file separator (e.g., / or \)
}