1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.millscript.loaders;
22
23 import org.millscript.commons.util.map.EHashMap;
24 import org.millscript.commons.vfs.VEntry;
25 import org.millscript.millscript.alert.Alerts;
26 import org.millscript.millscript.vm.Package;
27
28 /**
29 * This class is responsible for building an appropriate MillScript loader for
30 * a given file extension.
31 */
32 public class LoaderBuilder {
33
34 /**
35 * The mapping between file extensions and Loader Class objects.
36 */
37 private EHashMap< String, Class > loaders = new EHashMap< String, Class >();
38
39 /**
40 * Adds the specified Loader to this builder.
41 *
42 * @param extension the extension for the new Loader
43 * @param loaderClass the Loader for the specified extension
44 */
45 public void addLoader( final String extension, final Class loaderClass ) {
46 if ( loaderClass != null ) {
47
48 if ( Loader.class.isAssignableFrom( loaderClass ) ) {
49 loaders.insert( extension, loaderClass );
50 } else {
51 throw(
52 Alerts.fault(
53 "Loader's must inherit from Loader class"
54 ).culprit( "class", loaderClass ).mishap()
55 );
56 }
57 }
58 }
59
60 /**
61 * Adds the specified Loader to this builder.
62 *
63 * @param extension the extension for the new Loader
64 * @param loader the Loader for the specified extension
65 */
66 public void addLoader( final String extension, final Loader loader ) {
67 this.loaders.insert( extension, loader.getClass() );
68 }
69
70 /**
71 * Returns a Loader for the specified virtual filesystem entry, to load
72 * into the specified package.
73 *
74 * @param p the Package to load into
75 * @param entry the virtual entry to get a Loader for
76 * @return a Loader for the specified file
77 */
78 public Loader getLoaderFor( final Package p, final VEntry entry ) {
79
80 final String name = entry.getName();
81
82
83
84 int n = name.indexOf( '.' );
85 if ( n > 0 ) {
86
87 final String extension = name.substring( n + 1 );
88 final String symbol = name.substring( 0, n );
89
90 final Class loaderClass = loaders.get( extension );
91 if ( loaderClass != null ) {
92 final Loader loader = newLoaderInstance( loaderClass );
93 return loader.setLoader( p, symbol, entry );
94 }
95 }
96
97 return null;
98 }
99
100 /**
101 * Returns a new Loader instance for the specified Loader Class. This is a
102 * utility method.
103 *
104 * @param loaderClass the Loader Class to get an instance for
105 * @return a Loader, instantiated from the specified Loader Class
106 */
107 private static Loader newLoaderInstance( final Class loaderClass ) {
108 try {
109 return (Loader) loaderClass.newInstance();
110 } catch ( InstantiationException e ) {
111 throw(
112 Alerts.fault(
113 "Could not construct a loader for this file"
114 ).mishap()
115 );
116 } catch ( IllegalAccessException e ) {
117 throw(
118 Alerts.fault(
119 "Could not access a loader for this file"
120 ).mishap()
121 );
122 }
123 }
124
125 }