All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.enhydra.xml.xmlc.deferredparsing.XMLCDeferredParsingFactory Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: XMLCDeferredParsingFactory.java,v 1.3 2005/01/26 08:29:24 jkjome Exp $
 */

package org.enhydra.xml.xmlc.deferredparsing;

import java.io.File;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import org.enhydra.xml.xmlc.XMLCError;
import org.enhydra.xml.xmlc.XMLCLogger;
import org.enhydra.xml.xmlc.XMLCRuntimeException;
import org.enhydra.xml.xmlc.XMLCStdFactory;
import org.enhydra.xml.xmlc.XMLObject;

/**
 * Factory class to create instances of an XMLC-generated class with
 * "deferred parsing". Deferred parsing means that the DOM is parsed
 * from a file on first acess and re-parsed on subsequent acesses
 * whenever the DOM is out of date with regard to the source file.
 */
public class XMLCDeferredParsingFactory extends XMLCStdFactory {
    /**
     * Argument type for object constructor.
     */
    private static final Class[] CONSTRUCTOR_ARG_TYPES = {
        DocumentLoader.class
    };

    /**
     * Argument for object constructor.
     */
    private final Object[] CONSTRUCTOR_ARGS;

    /**
     * A list of resoruces path to search for the source files
     */
    private List fResourceDirList = new LinkedList();
    
    /**
     * A list of package prefix to removed while searching source
     * files under the resource path in fResourceDirList
     */
    private List fPackagePrefixList = new LinkedList();

    /**
     * default meta data file. This file is used as the meta file for
     * the dynamically added new pages
     */
    private String defaultMetaDataFile = null;

    /**
     * The class loader to create and load class for newly added
     * template to the system without pre-compiled class
     */
    private DynamicClassLoader dynamicClassLoader;

    /**
     * Constructor.
     * 
     * @param docLoader Document loader to use or null
     * @param classLoader Classloader used to load classes when a class name
     *  is specified.  If null, the system classload is used.
     * for the {@link StandardDocumentLoader}
     * @param logger XMLC logger or null for no logging.
     */
    public XMLCDeferredParsingFactory(DocumentLoader docLoader,
				      ClassLoader classLoader,
				      XMLCLogger logger) {
	super(classLoader, logger);
	
	if (docLoader == null) {
	    docLoader = new StandardDocumentLoader(Collections.synchronizedMap(new HashMap()));
	}
	CONSTRUCTOR_ARGS = new Object[] { docLoader };

	dynamicClassLoader = new DynamicClassLoader(classLoader, logger);
	// Initialize the document loader...
        docLoader.init(this);
    }

    /**
     * Create an object from a XMLC-generate class or subclass.
     * Don't call buildDocument();
     */
    private XMLObject createObject(Class xmlcBasedClass) {
        try {
            try {
                Constructor constructor = xmlcBasedClass.getConstructor(CONSTRUCTOR_ARG_TYPES);
                return (XMLObject)constructor.newInstance(CONSTRUCTOR_ARGS);
            } catch (NoSuchMethodException e) {
                // Class has not been compiled for reloading - try to load it as a standalone class
                return (XMLObject)xmlcBasedClass.newInstance();
            }
        } catch (Exception except) {
            throw new XMLCRuntimeException(except);
        }
    }

    /**
     * Create a new document instance.
     */
    protected XMLObject doCreate(Class xmlcBasedClass)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (xmlcBasedClass.isInterface()) {
            // Convert interface to class name.
            return doCreate(xmlcBasedClass.getName() + "Impl",
                            getDefaultClassLoader());
        } else {
            if (!XMLObject.class.isAssignableFrom(xmlcBasedClass)) {
                throw new XMLCError("class \"" + xmlcBasedClass.getName()
                                    + "\" does not implement \""
                                    + XMLObject.class.getName() + "\"");
            }
	    
            return  createObject(xmlcBasedClass);
        }
    }

    /**
     * Do actualy work of creating a new object given a name.
     */
    protected XMLObject doCreate(String xmlcClassName,
				 ClassLoader classLoader)
	throws ClassNotFoundException, IllegalAccessException, InstantiationException {

        if (classLoader != null) {
	    dynamicClassLoader.setDelegate(classLoader);
        } else {
	    dynamicClassLoader.setDelegate(getClass().getClassLoader());
	}

	return doCreate(dynamicClassLoader.loadClass(xmlcClassName));
    }

    /**
     * Create an XMLCObject from a source file
     */
    public XMLObject createFromFile (String filename) {
	String classname = filename.replace('/', '.');
	classname = classname.replace('\\', '.');
	classname = classname.replace(' ', '_');
	classname = "$$XMLC_GENERATED$$." + classname;

	return create(dynamicClassLoader.createClass(classname, filename));
    }

    /**
     * Add a resource directory
     * @param path path to the directory to be added
     */
    public void addResourceDir (String path) {
	synchronized(fResourceDirList) {
	    File dir = new File(path);
	    if (!fResourceDirList.contains(dir)) {
		if (dir.exists() && dir.isDirectory()) {
		    fResourceDirList.add(dir);
		}
	    }
	}
    }

    /**
     * Remove the given directory from the resource directory list
     * @param path path to be removed
     */
    public void removeResourceDir (String path) {
	synchronized(fResourceDirList) {
	    fResourceDirList.remove(path);
	}
    }

    /**
     * Return the resource directory list
     */
    List getResourceDirList () {
	return fResourceDirList;
    }

    /**
     * Add a package prefix to be checked
     * @param prefix package prefix to be added
     */
    public void addPackagePrefix (String prefix) {
	synchronized (fPackagePrefixList) {
	    prefix = prefix.replace('.', File.pathSeparatorChar);
	    if (!fPackagePrefixList.contains(prefix)) {
		fPackagePrefixList.add(prefix);
	    }
	}
    }

    /**
     * Remove the package prefix
     * @param prefix pacakge prefix to be removed
     */
    public void remove (String prefix) {
	synchronized (fPackagePrefixList) {
	    prefix = prefix.replace('.', File.pathSeparatorChar);
	    fPackagePrefixList.remove(prefix);
	}
    }
    
    /**
     * Get the package prefix list, the list of package path is
     * seperated with File.pathSeparator instead of '.'
     */
    List getPackagePrefixList () {
	return fPackagePrefixList;
    }

    /**
     * Set the default meta data file to be used by the dynamically
     * added pages
     * @param path path to the meta data file
     */
    public void setDefaultMetaDataPath(String path) {
	defaultMetaDataFile = path;
    }

    /**
     * Get the default meta data file to be used by the dynamically
     * added pages
     */
    public String getDefaultMetaDataFile() {
	return defaultMetaDataFile;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy