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.functions;
22  
23  import org.millscript.commons.vfs.VEntry;
24  import org.millscript.commons.vfs.VFile;
25  import org.millscript.commons.vfs.VFolder;
26  import org.millscript.millscript.alert.Alerts;
27  import org.millscript.millscript.tools.CastLibrary;
28  import org.millscript.millscript.vm.Machine;
29  import org.millscript.millscript.vm.Package;
30  
31  import java.io.IOException;
32  import java.io.InputStream;
33  import java.io.OutputStream;
34  import java.util.Iterator;
35  import java.util.List;
36  
37  /**
38   * This class implements the MillScript <code>copyToOutput</code> function.
39   * This function copies a static resource from the inventory to the current
40   * output folder. Static resources are stored in the inventory as a directory
41   * with an extension of <em>dir</em>.
42   */
43  public final class CopyToOutputFunction extends AbstractOutputFunction {
44  
45      /**
46       * Constructs a new <code>copyToOutput</code> function.
47       *
48       * @param pack  the package this function belongs to
49       */
50      public CopyToOutputFunction( final Package pack ) {
51          super( pack );
52      }
53  
54      /**
55       * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
56       */
57      @Override
58      public void apply( final Machine mc, final int nargs ) {
59          // TODO - We should support archives as static resources
60          if ( nargs == 1 ) {
61              // Pop the static resource virtual folder from the stack
62              final VFolder source = CastLibrary.toVFolder( mc.popObject() );
63              // Make the current output folder
64              final VFolder destination = this.makeCurrentWorkingFolder();
65              try {
66                  // Copy the contents of the source folder to the current output
67                  // folder
68                  this.copyDirectory( source, destination );
69              } catch ( IOException ex ) {
70                  throw(
71                      Alerts.eval(
72                          "IO exception copying static resources to output",
73                          null
74                      ).culprit( "message", ex.getMessage() ).mishap()
75                  );
76              }
77          } else {
78              checkNargs( mc, 1, nargs );
79          }
80      }
81  
82      /**
83       * Copies the contents of the source folder to the destination folder.
84       *
85       * @param source    the source virtual folder
86       * @param destination   the destination virtual folder
87       * @throws IOException  thrown if there is a problem copying a file from
88       * the static resource to the destination
89       */
90      private void copyDirectory( final VFolder source, final VFolder destination ) throws IOException {
91          final List entries = source.listEntries();
92          final Iterator it = entries.iterator();
93          while ( it.hasNext() ) {
94              final VEntry entry = (VEntry) it.next();
95              if ( entry instanceof VFolder ) {
96                  final VFolder destFolder = destination.make( entry.getName() );
97                  this.copyDirectory( (VFolder) entry, destFolder );
98              } else {
99                  this.copyFile( (VFile) entry, destination.getVFile( entry.getName() ) );
100             }
101         }
102     }
103 
104     /**
105      * Copies the specified source file to the destination.
106      *
107      * @param source    the source file
108      * @param destination   the destination file
109      * @throws IOException  thrown if there is a problem reading from the
110      * source or writing to the destination
111      */
112     public void copyFile( final VFile source, final VFile destination ) throws IOException {
113         // We should keep a reference to the input/output streams so that they
114         // can be explicitly closed
115         final InputStream is = source.getInputStream();
116         final OutputStream os = destination.getOutputStream();
117         // Get a buffer to use for copying the file
118         final byte[] buffer = new byte[1024];
119         int len = 0;
120         // Transfer everything from the input to the output
121         while ( ( len = is.read( buffer ) ) > 0 ) {
122              os.write( buffer, 0, len );
123         }
124         // Ensure the streams are closed
125         is.close();
126         os.close();
127     }
128 
129 }