<commit_before>/*
 * Axiom Stack Web Application Framework
 * Copyright (C) 2008  Axiom Software Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Axiom Software Inc., 11480 Commerce Park Drive, Third Floor, Reston, VA 20191 USA
 * email: <EMAIL>
 */
package axiom.scripting.rhino;

import java.io.*;
import java.lang.reflect.Method;
import java.util.HashSet;

import javax.activation.MimetypesFileTypeMap;

import org.mozilla.javascript.*;

import eu.medsea.util.MimeUtil;

import axiom.framework.ErrorReporter;
import axiom.framework.core.Application;
import axiom.objectmodel.INode;
import axiom.util.MimePart;
import axiom.util.TextExtractor;


public class FileObjectCtor extends FunctionObject {
    
    RhinoCore core;

    static Method fileObjCtor;

    static {
        try {
            fileObjCtor = FileObjectCtor.class.getMethod("jsConstructor", new Class[] {
                Context.class, Object[].class, Function.class, Boolean.TYPE });
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("Error getting FileObjectCtor.jsConstructor()");
        }
    }
    
    static HashSet tmpfiles = new HashSet();

    static final int attr = ScriptableObject.DONTENUM  |
                            ScriptableObject.PERMANENT |
                            ScriptableObject.READONLY;
    /**
     * Create and install a AxiomObject constructor.
     * Part of this is copied from o.m.j.FunctionObject.addAsConstructor().
     *
     * @param prototype
     */
    public FileObjectCtor(RhinoCore core, Scriptable prototype) {
        super("File", fileObjCtor, core.global);
        this.core = core;
        addAsConstructor(core.global, prototype);
    }

    /**
     *  This method is used as AxiomObject constructor from JavaScript.
     */
    public static Object jsConstructor(Context cx, Object[] args,
                                       Function ctorObj, boolean inNewExpr)
                         throws Exception {
    	if(args == null || (args != null && args.length == 0)){
    		throw new Exception("Invalid constructor parameters, new File(String|Mimepart, [optional] Boolean)");
    	}

        FileObjectCtor ctor = (FileObjectCtor) ctorObj;
        RhinoCore core = ctor.core;
        String protoname = ctor.getFunctionName();
                
        INode node = new axiom.objectmodel.db.Node("_" + protoname, protoname,
                core.app.getWrappedNodeManager());
        Scriptable proto = core.getPrototype(protoname);

        FileObject fobj = null; 

        if (args != null && args.length > 0 && (args[0] instanceof NativeJavaObject || args[0] instanceof MimePart || args[0] instanceof String)){
            Object obj = args[0];
            if (args[0] instanceof NativeJavaObject) {
                obj = ((NativeJavaObject) args[0]).unwrap();
            }
            if (obj instanceof MimePart || obj instanceof String) {
                fobj = new FileObject("File", core, node, proto, true);
            	boolean extractText = false;
                if(args.length > 1){
                	if(args[1] instanceof Scriptable){
        				Scriptable s = (Scriptable) args[1];
        				String className = s.getClassName();
        				if("Boolean".equals(className)) {
        					extractText = ScriptRuntime.toBoolean(s);
        				}
                	} else if(args[1] instanceof Boolean){
                		extractText = ((Boolean)args[1]).booleanValue();
                	}
                }
                FileObjectCtor.setup(fobj, node, args, core.app, !extractText);
            } else if (args[0] instanceof Scriptable) {
                Scriptable data = (Scriptable) args[0];
                fobj = new FileObject("File", core, node, proto, data);
            }
        } else if (args[0] instanceof Scriptable) {
        	Scriptable data = (Scriptable) args[0];
        	fobj = new FileObject("File", core, node, proto, data);
        }

        return fobj;
    }
    
    protected static String setup(FileObject fobj, INode node, Object[] args, 
    								Application app, boolean extractContent) {
        String ret = null;        
        
        if (args != null && args.length > 0) {
            if (args[0] == null) {
                throw new RuntimeException("FileObjectCtor: first argument cannot be null!");
            }
            
            if (args[0] instanceof NativeJavaObject || args[0] instanceof MimePart) {
                MimePart mp;
                if (args[0] instanceof NativeJavaObject) {
                    mp = (MimePart) ((NativeJavaObject) args[0]).unwrap();
                } else {
                    mp = (MimePart) args[0];
                }
                
                String filename = mp.getName();
                node.setString(FileObject.FILE_NAME, filename);
                node.setString(FileObject.ACCESSNAME, generateAccessName(filename));
                
                final String tmpdir = (String) FileObject.tmpDirs.get(app.getName());
                
                filename = generateTmpFileName(filename, tmpdir);
                
                mp.writeToFile(tmpdir, filename);
                fobj.tmpPath = tmpdir + filename; 
                                
                node.setInteger(FileObject.FILE_SIZE, mp.contentLength);
                String mimetype = mp.contentType;
                if (mimetype == null || mimetype.equals("application/octet-stream")) {
                	mimetype = MimeUtil.getMimeType(new File(fobj.tmpPath));
                }
                node.setString(FileObject.CONTENT_TYPE, mimetype);
                node.setString(FileObject.RENDERED_CONTENT, "false");
                node.setJavaObject(FileObject.SELF, fobj);
                node.setString(FileObject.FILE_UPLOAD, "true");
                
                String text = extractContent ? extractText(fobj.tmpPath, app) : null;
                if (text != null) {
                    node.setString(FileObject.CONTENT, text);
                }
                
                ret = fobj.tmpPath;
            } else if (args[0] instanceof String) {
                final String path = (String) args[0];
                final File file = new File(path);
                
                if (!file.exists() || !file.isFile()) {
                    throw new RuntimeException("FileObjectCtor: " + path + " does not point to a readable file");
                }
                
                String filename = file.getName();
                node.setString(FileObject.FILE_NAME, filename);
                node.setString(FileObject.ACCESSNAME, FileObjectCtor.generateAccessName(filename));
                
                fobj.tmpPath = file.getAbsolutePath(); 
                                
                node.setInteger(FileObject.FILE_SIZE, file.length());
                node.setString(FileObject.CONTENT_TYPE, guessContentType(file));
                node.setString(FileObject.RENDERED_CONTENT, "false");
                node.setJavaObject(FileObject.SELF, fobj);
                node.setString(FileObject.FILE_UPLOAD, "false");
                
                String text = extractContent ? extractText(fobj.tmpPath, app) : null;
                if (text != null) {
                    node.setString(FileObject.CONTENT, text);
                }
                
                ret = fobj.tmpPath;
            } else {
                throw new RuntimeException("FileObjectCtor: first argument to constructor must be the MimePart object or the location of a file");
            }
        } else {
            throw new RuntimeException("FileObjectCtor: must specify arguments to the File constructor!");
        }    
<commit_msg>Added code to better guess the mime-type upon creation. This uses our original guestimation approach, but if the content-type still is null or application/octet-stream, it is checked with mime-util. This resolves most issues we'd see with mime-types.<commit_after>/*
 * Axiom Stack Web Application Framework
 * Copyright (C) 2008  Axiom Software Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Axiom Software Inc., 11480 Commerce Park Drive, Third Floor, Reston, VA 20191 USA
 * email: <EMAIL>
 */
package axiom.scripting.rhino;

import java.io.*;
import java.lang.reflect.Method;
import java.util.HashSet;

import javax.activation.MimetypesFileTypeMap;

import org.mozilla.javascript.*;

import eu.medsea.util.MimeUtil;

import axiom.framework.ErrorReporter;
import axiom.framework.core.Application;
import axiom.objectmodel.INode;
import axiom.util.MimePart;
import axiom.util.TextExtractor;


public class FileObjectCtor extends FunctionObject {
    
    RhinoCore core;

    static Method fileObjCtor;

    static {
        try {
            fileObjCtor = FileObjectCtor.class.getMethod("jsConstructor", new Class[] {
                Context.class, Object[].class, Function.class, Boolean.TYPE });
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("Error getting FileObjectCtor.jsConstructor()");
        }
    }
    
    static HashSet tmpfiles = new HashSet();

    static final int attr = ScriptableObject.DONTENUM  |
                            ScriptableObject.PERMANENT |
                            ScriptableObject.READONLY;
    /**
     * Create and install a AxiomObject constructor.
     * Part of this is copied from o.m.j.FunctionObject.addAsConstructor().
     *
     * @param prototype
     */
    public FileObjectCtor(RhinoCore core, Scriptable prototype) {
        super("File", fileObjCtor, core.global);
        this.core = core;
        addAsConstructor(core.global, prototype);
    }

    /**
     *  This method is used as AxiomObject constructor from JavaScript.
     */
    public static Object jsConstructor(Context cx, Object[] args,
                                       Function ctorObj, boolean inNewExpr)
                         throws Exception {
    	if(args == null || (args != null && args.length == 0)){
    		throw new Exception("Invalid constructor parameters, new File(String|Mimepart, [optional] Boolean)");
    	}

        FileObjectCtor ctor = (FileObjectCtor) ctorObj;
        RhinoCore core = ctor.core;
        String protoname = ctor.getFunctionName();
                
        INode node = new axiom.objectmodel.db.Node("_" + protoname, protoname,
                core.app.getWrappedNodeManager());
        Scriptable proto = core.getPrototype(protoname);

        FileObject fobj = null; 

        if (args != null && args.length > 0 && (args[0] instanceof NativeJavaObject || args[0] instanceof MimePart || args[0] instanceof String)){
            Object obj = args[0];
            if (args[0] instanceof NativeJavaObject) {
                obj = ((NativeJavaObject) args[0]).unwrap();
            }
            if (obj instanceof MimePart || obj instanceof String) {
                fobj = new FileObject("File", core, node, proto, true);
            	boolean extractText = false;
                if(args.length > 1){
                	if(args[1] instanceof Scriptable){
        				Scriptable s = (Scriptable) args[1];
        				String className = s.getClassName();
        				if("Boolean".equals(className)) {
        					extractText = ScriptRuntime.toBoolean(s);
        				}
                	} else if(args[1] instanceof Boolean){
                		extractText = ((Boolean)args[1]).booleanValue();
                	}
                }
                FileObjectCtor.setup(fobj, node, args, core.app, !extractText);
            } else if (args[0] instanceof Scriptable) {
                Scriptable data = (Scriptable) args[0];
                fobj = new FileObject("File", core, node, proto, data);
            }
        } else if (args[0] instanceof Scriptable) {
        	Scriptable data = (Scriptable) args[0];
        	fobj = new FileObject("File", core, node, proto, data);
        }

        return fobj;
    }
    
    protected static String setup(FileObject fobj, INode node, Object[] args, 
    								Application app, boolean extractContent) {
        String ret = null;        
        
        if (args != null && args.length > 0) {
            if (args[0] == null) {
                throw new RuntimeException("FileObjectCtor: first argument cannot be null!");
            }
            
            if (args[0] instanceof NativeJavaObject || args[0] instanceof MimePart) {
                MimePart mp;
                if (args[0] instanceof NativeJavaObject) {
                    mp = (MimePart) ((NativeJavaObject) args[0]).unwrap();
                } else {
                    mp = (MimePart) args[0];
                }
                
                String filename = mp.getName();
                node.setString(FileObject.FILE_NAME, filename);
                node.setString(FileObject.ACCESSNAME, generateAccessName(filename));
                
                final String tmpdir = (String) FileObject.tmpDirs.get(app.getName());
                
                filename = generateTmpFileName(filename, tmpdir);
                
                mp.writeToFile(tmpdir, filename);
                fobj.tmpPath = tmpdir + filename; 
                                
                node.setInteger(FileObject.FILE_SIZE, mp.contentLength);
                String mimetype = mp.contentType;
                if (mimetype == null || mimetype.equals("application/octet-stream")) {
                	mimetype = MimeUtil.getMimeType(new File(fobj.tmpPath));
                }
                node.setString(FileObject.CONTENT_TYPE, mimetype);
                node.setString(FileObject.RENDERED_CONTENT, "false");
                node.setJavaObject(FileObject.SELF, fobj);
                node.setString(FileObject.FILE_UPLOAD, "true");
                
                String text = extractContent ? extractText(fobj.tmpPath, app) : null;
                if (text != null) {
                    node.setString(FileObject.CONTENT, text);
                }
                
                ret = fobj.tmpPath;
            } else if (args[0] instanceof String) {
                final String path = (String) args[0];
                final File file = new File(path);
                
                if (!file.exists() || !file.isFile()) {
                    throw new RuntimeException("FileObjectCtor: " + path + " does not point to a readable file");
                }
                
                String filename = file.getName();
                node.setString(FileObject.FILE_NAME, filename);
                node.setString(FileObject.ACCESSNAME, FileObjectCtor.generateAccessName(filename));
                
                fobj.tmpPath = file.getAbsolutePath(); 
                                
                node.setInteger(FileObject.FILE_SIZE, file.length());
                String mimetype = guessContentType(file);
                if (mimetype == null || mimetype.equals("application/octet-stream")) {
                	mimetype = MimeUtil.getMimeType(new File(fobj.tmpPath));
                }
                node.setString(FileObject.CONTENT_TYPE, mimetype);
                node.setString(FileObject.RENDERED_CONTENT, "false");
                node.setJavaObject(FileObject.SELF, fobj);
                node.setString(FileObject.FILE_UPLOAD, "false");
                
                String text = extractContent ? extractText(fobj.tmpPath, app) : null;
                if (text != null) {
                    node.setString(FileObject.CONTENT, text);
                }
                
                ret = fobj.tmpPath;
            } else {
                throw new RuntimeException("FileObjectCtor: first argument to constructor must be the MimePart object or the location of a file");
            }
        } else {
            throw new RuntimeException("FileObjectCtor: must specify arguments to the File constructor!");
        }    

{'fraction_non_alphanumeric': 0.09431434230455552, 'fraction_numerical': 0.004776884539205406, 'mean_word_length': 1.8861802286482852, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5101639', 'n_tokens_mistral': 4617, 'n_tokens_neox': 4379, 'n_words': 1204}