View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2004-2005 Kevin Rogers
4   //
5   // This file is part of MillScript.
6   //
7   // MillScript is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
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              // Check the retrieved class is an extension of a Loader
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          // Get the file name
80          final String name = entry.getName();
81  
82          // Get the file name extension. We look for the first period in the
83          // file name, as MillScript doesn't support periods in symbol names.
84          int n = name.indexOf( '.' );
85          if ( n > 0 ) {
86              // We found an extension, so split up the file name
87              final String extension = name.substring( n + 1 );
88              final String symbol = name.substring( 0, n );
89              // Get the loader Class for this extension
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          // We haven't found a loader, so return null
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 }