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

com.draagon.meta.loader.MetaDataLoader Maven / Gradle / Ivy

/*
 * Copyright 2003 Draagon Software LLC. All Rights Reserved.
 *
 * This software is the proprietary information of Draagon Software LLC.
 * Use is subject to license terms.
 */
package com.draagon.meta.loader;

import com.draagon.meta.MetaData;
import com.draagon.meta.MetaDataNotFoundException;
import com.draagon.meta.attr.MetaAttribute;
import com.draagon.meta.loader.types.TypesConfig;
import com.draagon.meta.loader.mojo.MojoSupport;
import com.draagon.meta.object.MetaObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 *  MetaDataLoader with common functions for all MetaDataLoaders
 */
public class MetaDataLoader extends MetaData implements MojoSupport {

    private final static Log log = LogFactory.getLog(MetaDataLoader.class);

    public final static String TYPE_LOADER = "loader";
    public final static String SUBTYPE_MANUAL = "manual";

    // TODO:  Allow for custom configurations for overloaded MetaDataLoaders
    private final LoaderOptions loaderOptions;
    private TypesConfig typesConfig = null;

    private boolean isRegistered = false;
    private boolean isInitialized = false;
    private boolean isDestroyed = false;
    
    /**
     * Constructs a new MetaDataLoader
     * @param subtype The subType for the metadata loader
     */
    public MetaDataLoader(LoaderOptions loaderOptions, String subtype ) {
        this( loaderOptions, subtype, TYPE_LOADER + "-" + System.currentTimeMillis());
    }

    /**
     * Constructs a new MetaDataLoader
     * @param subtype The subtype of the metadata loader
     * @param name The name of the metadata loader
     */
    public MetaDataLoader(LoaderOptions loaderOptions, String subtype, String name ) {
        super( TYPE_LOADER, subtype, name );
        this.loaderOptions = loaderOptions;
    }

    /**
     * Manually construct a MetaDataLoader.  Usually used for unit testing.
     * @param name The name of the Manually create MetaDataLoader
     * @return The created MetaDataLoader
     */
    public static MetaDataLoader createManual( boolean shouldRegister, String name ) {
        return new MetaDataLoader(
                LoaderOptions.create( false, false, false),
                        SUBTYPE_MANUAL, name );
    }

    ///////////////////////////////////////////////////////////////////////
    // Configs

    public LoaderOptions getLoaderOptions() {
        return loaderOptions;
    }

    public  T getTypesConfig() {
        return (T) typesConfig;
    }

    public  MetaDataLoader setTypesConfig(T typesConfig ) {
        this.typesConfig = typesConfig;
        return this;
    }

    /**
     * Check the state of the MetaDataLoader to ensure it is initialized and not destroyed();
     */
    protected void checkState() {
        if ( !isInitialized ) throw new IllegalStateException( "MetaDataLoader [" + getName() + "] was not initialized" );
        if ( isDestroyed ) throw new IllegalStateException( "MetaDataLoader [" + getName() + "] is destroyed" );
    }


    ////////////////////////////////////////////////////////////////////////////////////////////
    // MOJO Support Methods
    private String mojoSourceDir=null;

    @Override
    public void mojoSetSourceDir( String sourceDir ) {
        File sd = new File(sourceDir);
        if ( !sd.exists() ) throw new IllegalStateException( "MojoSourceDir ["+sourceDir+"] does not exist");
        mojoSourceDir = sourceDir;
    }

    @Override
    public void mojoSetSources(List sourceList) {

        if ( sourceList == null ) throw new IllegalArgumentException(
                "sourceURIList was null on setURIList for Loader: " + toString());

        mojoProcessSources( mojoSourceDir, sourceList );
    }

    protected void mojoProcessSources( String sourceDir, List sourceList ) {

        String name = this.getClass().getSimpleName();
        if ( sourceList == null ) throw new IllegalArgumentException(
                "sourceURIList was null on setURIList for " + name);
        if ( sourceList.size() > 0  ) throw new IllegalArgumentException( name +
                " does not support URI sources");
    }

    protected void mojoInitArgs( Map args ) {

        if ( args == null ) return;

        if ( args.get( MojoSupport.ARG_REGISTER ) != null ) {
            getLoaderOptions().setShouldRegister( Boolean.parseBoolean( args.get( MojoSupport.ARG_REGISTER ) ));
        }
        if ( args.get( MojoSupport.ARG_VERBOSE ) != null ) {
            getLoaderOptions().setVerbose( Boolean.parseBoolean( args.get( MojoSupport.ARG_VERBOSE ) ));
        }
        if ( args.get( MojoSupport.ARG_STRICT ) != null ) {
            getLoaderOptions().setStrict( Boolean.parseBoolean( args.get( MojoSupport.ARG_STRICT ) ));
        }
    }

    @Override
    public void mojoInit( Map args ) {
        init();
    }

    ////////////////////////////////////////////////////////////////////////////////////////////
    // Initialization Methods

    /**
     * Initialize the MetaDataLoader.  It will prevent a second init call.
     * @return This MetaDataLoader
     */
    public MetaDataLoader init() {

        if ( isInitialized ) throw new IllegalStateException( "MetaDataLoader [" + getName() + "] was already initialized" );

        if ( loaderOptions.isVerbose() ) {
            log.info("Loading the [" + getClass().getSimpleName() + "] MetaDataLoader with name [" + getName() + "]" );
        }

        isInitialized = true;

        if ( loaderOptions.shouldRegister() ) {
            register();
        }

        return this;
    }

    @Override
    public void validate() {
        super.validate();
    }

    /**
     * Returns if the MetaDataLoader is initialized
     * @return True if initialized
     */
    public boolean isInitialized() {
        return isInitialized;
    }

    /**
     * Register this MetaDataLoader with the MetaDataRegistry
     */
    public MetaDataLoader register() {
        if ( !isRegistered ) {
            MetaDataRegistry.registerLoader(this);
        }
        isRegistered = true;
        return this;
    }

    /**
     * Returns whether the MetaDataLoader in the MetaDataRegistry
     */
    public boolean isRegistered() {
        return isRegistered;
    }

    /**
     * Gets the primary MetaData class
     */
    public final Class getMetaDataClass() {
        return MetaDataLoader.class;
    }

    /** Wrap the MetaDataLoader */
    public MetaDataLoader overload() {
        throw new IllegalStateException( "You cannot wrap a MetaDataLoader!" );
    }

    /**
     * Sets an attribute on the MetaClass
     */
    public MetaDataLoader addMetaAttr(MetaAttribute attr) {
        return addChild(attr);
    }

    /**
     * Whether the MetaDataLoader handles the object specified
     */
    protected boolean handles(Object obj) {
        checkState();
        if (getMetaObjectFor(obj) != null) {
            return true;
        }
        return false;
    }

    /**
     * Retrieves a collection of all Meta Classes
     */
    public List getMetaDataOfType( String type ) {
        return getMetaDataOfType(type, true);
    }

    /**
     * Retrieves a collection of all Meta Classes
     */
    public List getMetaDataOfType( String type, boolean includeParentData ) {
        checkState();
        return getChildrenOfType(type,includeParentData);
    }


    /**
     * Retrieves a collection of all Meta Classes
     */
    public List getMetaObjects() {
        checkState();
        return getChildren( MetaObject.class, true );
    }

    /**
     * Retrieves a collection of all Meta Classes
     */
    public MetaObject getMetaObjectByName(String name ) {
        checkState();
        return (MetaObject) getChildOfType( MetaObject.TYPE_OBJECT, name );
    }

    /**
     * Return the matching object instance
     */
    public  T newObjectInstance(Class clazz) throws ClassNotFoundException {
        for(MetaObject mo : getMetaObjects()) {
            if (mo.getObjectClass().equals(clazz)) {
                return (T) mo.newInstance();
            }
        }
        throw new ClassNotFoundException("Could not find MetaObject for class ["+clazz.getName()+"]");
    }

    /**
     * Gets the MetaObject of the specified Object
     */
    public MetaObject getMetaObjectFor(Object obj) {
        checkState();
        for (MetaObject mc : getChildren( MetaObject.class, true )) {
            if (mc.produces(obj)) {
                return mc;
            }
        }

        return null;
    }


    /**
     * Retrieves a collection of all Meta Classes
     */
    public  List getMetaData(Class c ) {
        return getMetaData(c, true);
    }

    /**
     * Retrieves a collection of all Meta Classes
     */
    public  List getMetaData( Class c, boolean includeParentData ) {
        checkState();
        return getChildren(c,includeParentData);
    }


    /**
     * Gets the MetaData with the specified Class type and name
     */
    public  N getMetaDataByName( Class c, String metaDataName) throws MetaDataNotFoundException {

        checkState();

        String KEY = "QuickCache-"+c.getName()+"-"+metaDataName;

        MetaData mc = (MetaData) getCacheValue(KEY);
        if (mc == null) {
            synchronized( this ) {

                mc = (MetaData) getCacheValue(KEY);
                if (mc == null) {
                    for (MetaData mc2 : getMetaData( c )) {
                        if (mc2.getName().equals(metaDataName)) {
                            mc = mc2;
                            break;
                        }
                    }

                    if (mc != null) {
                        setCacheValue(KEY, mc);
                    }
                }
            }

            if (mc == null) {
                throw new MetaDataNotFoundException( "MetaData with name [" + metaDataName + "] not found in MetaDataLoader [" + toString() + "]", metaDataName );
            }
        }


        return (N) mc;
    }

    /**
     * Gets the MetaData with the specified name in parent hierarchy.
     * 

* Only uses direct 'super' relationship, not 'inherits' */ protected List getMetaDataBySuper(String metaDataName, List objects) throws MetaDataNotFoundException { checkState(); String KEY = "QuickCacheDerived-" + metaDataName; List result = (List) getCacheValue(KEY); if (result == null) { synchronized (this) { result = (List) getCacheValue(KEY); if (result == null) { result = new ArrayList<>(); for (MetaObject mo : objects) { if (null != mo.getSuperObject()) { if (mo.getSuperObject().getName().equals(metaDataName)) { result.add( mo); result.addAll( getMetaDataBySuper(mo.getName(), objects)); } } } setCacheValue(KEY, result); // Build the sub-trees as we go } } } return result; } /** * Gets the MetaData with the specified name in parent hierarchy. *

* Only uses direct 'super' relationship, not 'inherits' */ public List getMetaDataBySuper(String metaDataName) throws MetaDataNotFoundException { checkState(); String KEY = "QuickCacheDerived-" + metaDataName; List result; result = (List) getCacheValue(KEY); if (result == null) { synchronized (this) { result = (List) getCacheValue(KEY); if (result == null) { List objects = getMetaObjects(); // Delegate to a second level, so we don't have to keep retrieving the list of all MetaObjects result = getMetaDataBySuper(metaDataName, objects); // rely on delegate function to set the cache } } } return result; } /** * Removes the MetaData * @deprecated Use MetaData.deleteChild() */ public void removeMetaData( Class c, String name) throws MetaDataNotFoundException { checkState(); deleteChild(getMetaDataByName( c, name)); } /** * Adds the MetaData * @deprecated Use MetaData.addChild */ public void addMetaData(MetaData mc) { checkState(); addChild(mc); } /** * Lookup the specified class by name * @param className * @return */ public Class loadClass(String className ) throws ClassNotFoundException { checkState(); try { return getClass().getClassLoader().loadClass( className ); } catch (ClassNotFoundException e) { throw new ClassNotFoundException("Specified Java Class [" + className + "] was not found: " + e.getMessage(), e); } } /** * Adds the child MetaData */ @Override public MetaDataLoader addChild(MetaData mc) { checkState(); return super.addChild(mc); } /** * Unloads the MetaDataLoader */ public void destroy() { if ( isDestroyed ) throw new IllegalStateException( "MetaDataLoader [" + getName() + "] was already destroyed!" ); if ( loaderOptions.isVerbose() ) { log.info("Destroying the [" + getName() + "] MetaDataLoader"); } // Remove all classes clearChildren(); isDestroyed = true; // Unregister the class loader if ( isRegistered ) { MetaDataRegistry.unregisterLoader(this); } } public boolean isDestroyed() { return isDestroyed; } //////////////////////////////////////////////////// // MISC METHODS public String toString() { if (getParent() == null) { return getClass().getSimpleName() + "[" + getSubTypeName() + ":" + getName() + "]"; } else { return getClass().getSimpleName() + "[" + getSubTypeName() + ":" + getName() + "@" + getParent().toString() + "]"; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy